]> git.itanic.dy.fi Git - maemo-mapper/commitdiff
Made changes mentioned in the changelog in preparation for the release
authorgnuite <gnuite@gmail.com>
Fri, 2 Nov 2007 01:32:40 +0000 (01:32 +0000)
committergnuite <gnuite@gmail.com>
Fri, 2 Nov 2007 01:32:40 +0000 (01:32 +0000)
of Maemo Mapper v2.0.

git-svn-id: svn+ssh://garage/var/lib/gforge/svnroot/maemo-mapper/trunk@112 6c538b50-5814-0410-93ad-8bdf4c0149d1

53 files changed:
LICENSE
Makefile.am
autogen.sh
configure.ac
data/Makefile.am
data/help/Makefile.am
data/help/en_US/maemomapper.xml.in
data/help/fi_FI/maemomapper.xml.in [new file with mode: 0644]
debian/changelog
debian/rules
dpkg-build.sh [deleted file]
po/POTFILES.in
po/bg_BG.po
po/en_US.po
po/es_ES.po
po/fi_FI.po
po/it_IT.po
po/nl_NL.po
po/update-po.sh
src/Makefile.am
src/cmenu.c [new file with mode: 0644]
src/cmenu.h [new file with mode: 0644]
src/data.c [new file with mode: 0644]
src/data.h [new file with mode: 0644]
src/defines.h [new file with mode: 0644]
src/display.c [new file with mode: 0644]
src/display.h [new file with mode: 0644]
src/gdk-pixbuf-rotate.c [new file with mode: 0644]
src/gdk-pixbuf-rotate.h [new file with mode: 0644]
src/gps.c [new file with mode: 0644]
src/gps.h [new file with mode: 0644]
src/gpx.c [new file with mode: 0644]
src/gpx.h [new file with mode: 0644]
src/input.c [new file with mode: 0644]
src/input.h [new file with mode: 0644]
src/maemo-mapper.c [deleted file]
src/main.c [new file with mode: 0644]
src/main.h [new file with mode: 0644]
src/maps.c [new file with mode: 0644]
src/maps.h [new file with mode: 0644]
src/marshal.c [new file with mode: 0644]
src/marshal.h [new file with mode: 0644]
src/menu.c [new file with mode: 0644]
src/menu.h [new file with mode: 0644]
src/path.c [new file with mode: 0644]
src/path.h [new file with mode: 0644]
src/poi.c [new file with mode: 0644]
src/poi.h [new file with mode: 0644]
src/settings.c [new file with mode: 0644]
src/settings.h [new file with mode: 0644]
src/types.h [new file with mode: 0644]
src/util.c [new file with mode: 0644]
src/util.h [new file with mode: 0644]

diff --git a/LICENSE b/LICENSE
index e37680cf1385db400bff88ac103d30e876a5103e..94a9ed024d3859793618152ea559a168bbcbb5e2 100644 (file)
--- a/LICENSE
+++ b/LICENSE
-                   GNU GENERAL PUBLIC LICENSE
-                      Version 2, June 1991
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
 
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
  Everyone is permitted to copy and distribute verbatim copies
  of this license document, but changing it is not allowed.
 
-                           Preamble
+                            Preamble
 
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.)  You can apply it to
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
 your programs, too.
 
   When we speak of free software, we are referring to freedom, not
 price.  Our General Public Licenses are designed to make sure that you
 have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
 
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
 
   For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
 
   The precise terms and conditions for copying, distribution and
 modification follow.
 
-                   GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
 this License.
 
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
 otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
 be similar in spirit to the present version, but may differ in detail to
 address new problems or concerns.
 
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-                           NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-                    END OF TERMS AND CONDITIONS
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
index 7b632736600cf7e2addcfcd8e313e3ab890bf8eb..85d9487606f03f6dd7d7f17fd4758959a0f261ae 100644 (file)
@@ -1,21 +1,20 @@
 #
-# This file is part of maemo-mapper
+# Copyright (C) 2006, 2007 John Costigan.
 #
-# Copyright (C) 2006 John Costigan.
+# This file is part of Maemo Mapper.
 #
-# This program is free software; you can redistribute it and/or modify
+# Maemo Mapper is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
+# the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 #
-# This program is distributed in the hope that it will be useful,
+# Maemo Mapper is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 #
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+# You should have received a copy of the GNU General Public License
+# along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
 #
  
 EXTRA_DIST = \
index a6a3df6c584cd54245165634dc3389cd9d2ae871..33a4026a3203c9fc2f227d9e293cf9b8ff041c60 100755 (executable)
@@ -1,23 +1,22 @@
 #!/bin/sh
 
 #
-# This file is part of maemo-mapper
+# Copyright (C) 2006, 2007 John Costigan.
 #
-# Copyright (C) 2006 John Costigan.
+# This file is part of Maemo Mapper.
 #
-# This program is free software; you can redistribute it and/or modify
+# Maemo Mapper is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
+# the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 #
-# This program is distributed in the hope that it will be useful,
+# Maemo Mapper is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 #
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+# You should have received a copy of the GNU General Public License
+# along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
 #
  
 set -x
index 983123ac699b68163cdc464b965458330ff60cfc..b1c6fb8b7a9a73c149bf30a4c5357a87aaed38df 100644 (file)
@@ -1,25 +1,24 @@
 #
-# This file is part of maemo-mapper
+# Copyright (C) 2006, 2007 John Costigan.
 #
-# Copyright (C) 2006 John Costigan.
+# This file is part of Maemo Mapper.
 #
-# This program is free software; you can redistribute it and/or modify
+# Maemo Mapper is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
+# the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 #
-# This program is distributed in the hope that it will be useful,
+# Maemo Mapper is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 #
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+# You should have received a copy of the GNU General Public License
+# along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
 #
 
 AC_INIT(Makefile.am)
-AM_INIT_AUTOMAKE(maemo-mapper, 1.4.7)
+AM_INIT_AUTOMAKE(maemo-mapper, 2.0)
 
 AC_PROG_CPP
 AC_CONFIG_HEADERS(src/config.h)
@@ -30,7 +29,7 @@ PKG_CHECK_MODULES(GTK, gtk+-2.0)
 AC_SUBST(GTK_LIBS)
 AC_SUBST(GTK_CFLAGS)
 
-PKG_CHECK_MODULES(OSSO, libosso >= 1 libossohelp osso-ic)
+PKG_CHECK_MODULES(OSSO, libosso >= 1 libossohelp)
 AC_SUBST(OSSO_LIBS)
 AC_SUBST(OSSO_CFLAGS)
 
@@ -50,14 +49,14 @@ PKG_CHECK_MODULES(LIBXML2, libxml-2.0 >= 2.6.16)
 AC_SUBST(LIBXML2_LIBS)
 AC_SUBST(LIBXML2_CFLAGS)
 
-PKG_CHECK_MODULES(LIBCURL, libcurl)
-AC_SUBST(LIBCURL_LIBS)
-AC_SUBST(LIBCURL_CFLAGS)
-
 PKG_CHECK_MODULES(SQLITE, sqlite3)
 AC_SUBST(SQLITE_LIBS)
 AC_SUBST(SQLITE_CFLAGS)
 
+PKG_CHECK_MODULES(CONIC, conic)
+AC_SUBST(CONIC_LIBS)
+AC_SUBST(CONIC_CFLAGS)
+
 
 # Localisation
 localedir=`$PKG_CONFIG osso-af-settings --variable=localedir`
@@ -92,6 +91,8 @@ helpfile_enusdir=$datadir/osso-help/en_US
 AC_SUBST(helpfile_enusdir)
 helpfile_engbdir=$datadir/osso-help/en_GB
 AC_SUBST(helpfile_engbdir)
+helpfile_fifidir=$datadir/osso-help/fi_FI
+AC_SUBST(helpfile_fifidir)
 
 # Hildon control panel plugin install directories
 pluginlibdir=`$PKG_CONFIG hildon-control-panel --variable=plugindir`
index cfb22016d341827541c51e1855fdaa41cf296d82..d8e19c9d82917c978ac9c2531b2b7ae91f98a937 100644 (file)
@@ -1,21 +1,20 @@
 #
-# This file is part of maemo-mapper
+# Copyright (C) 2006, 2007 John Costigan.
 #
-# Copyright (C) 2006 John Costigan.
+# This file is part of Maemo Mapper.
 #
-# This program is free software; you can redistribute it and/or modify
+# Maemo Mapper is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
+# the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 #
-# This program is distributed in the hope that it will be useful,
+# Maemo Mapper is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 #
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+# You should have received a copy of the GNU General Public License
+# along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
 #
  
 serviceentry_DATA = com.gnuite.maemo_mapper.service
index 2d644e1a52234c7458163bc5f6ada862a3f6dbc4..d68a2b47565bb68a2b975802515f8a8096898623 100644 (file)
@@ -1,27 +1,27 @@
 #
-# This file is part of maemo-mapper
+# Copyright (C) 2006, 2007 John Costigan.
 #
-# Copyright (C) 2006 John Costigan.
+# This file is part of Maemo Mapper.
 #
-# This program is free software; you can redistribute it and/or modify
+# Maemo Mapper is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
+# the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 #
-# This program is distributed in the hope that it will be useful,
+# Maemo Mapper is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 #
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+# You should have received a copy of the GNU General Public License
+# along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
 #
  
 helpfile_enus_DATA = en_US/maemomapper.xml
 helpfile_engb_DATA = en_GB/maemomapper.xml
+helpfile_fifi_DATA = fi_FI/maemomapper.xml
 
-EXTRA_DIST = $(helpfile_engb_DATA) $(helpfile_engb_DATA)
+EXTRA_DIST = $(helpfile_engb_DATA) $(helpfile_engb_DATA) $(helpfile_fifi_DATA)
 
 # Replace version in help files
 %.xml: %.xml.in
index 14421cdf76cbddf8ecdeebe246285bbdff3561ff..2c6c2b0693c05df0f32907388f2193b943607bc5 100644 (file)
         </listitem>
         <listitem>
           <display_text>Insert Break</display_text> - Artificially insert a
-         break in your current track data.  This simulates the loss and
-         re-acquisition of a GPS fix, and it can be used to track, for
-         example, refueling stops.
+          break in your current track data.  This simulates the loss and
+          re-acquisition of a GPS fix, and it can be used to track, for
+          example, refueling stops.
         </listitem>
         <listitem>
           <display_text>Insert Mark</display_text> - Artificially insert a
-         mark with a description in your current track data.  This can be
-         used to mark important landmarks.
+          mark with a description in your current track data.  This can be
+          used to mark important landmarks.
         </listitem>
         <listitem>
           <display_text>Show Distance from Last Break</display_text> - Show
       </para>
       <list>
         <listitem>
-         <display_text>Zoom In</display_text> - Zoom in by one zoom level.
-         You can also use the <graphic
-           filename="2686KEY_zoom_in"/> button.
+          <display_text>Zoom In</display_text> - Zoom in by one zoom level.
+          You can also use the <graphic
+            filename="2686KEY_zoom_in"/> button.
         </listitem>
         <listitem>
-         <display_text>Zoom Out</display_text> - Zoom out by one zoom
-         level.  You can also use the <graphic
-           filename="2686KEY_zoom_out"/> button.
+          <display_text>Zoom Out</display_text> - Zoom out by one zoom
+          level.  You can also use the <graphic
+            filename="2686KEY_zoom_out"/> button.
         </listitem>
         <listitem>
           <display_text>Full Screen</display_text> - Toggle full-screen
           mode.  You can also use the <graphic
-           filename="2686KEY_full_screen"/> button to toggle
-         full-screen mode.
+            filename="2686KEY_full_screen"/> button to toggle
+          full-screen mode.
         </listitem>
         <listitem>
-         <display_text>Scale</display_text> - Toggle the display of the
-         scale.
+          <display_text>Scale</display_text> - Toggle the display of the
+          scale.
         </listitem>
         <listitem>
           <display_text>Route</display_text> - Toggle the display of routes.
         </listitem>
         <listitem>
           <display_text>About...</display_text> - Display version and
-         copyright information.
+          copyright information.
         </listitem>
         <listitem>
           <display_text>Close</display_text> - Close Maemo Mapper.
       <topictitle>Managing Repositories</topictitle>
       <context contextUID="help_maemomapper_repoman"/>
       <para>
-        In Maemo Mapper, map data is divided into specific areas called
+        In Maemo Mapper, map data is divided into specific units called
         <i>repositories</i>.  A repository is a source of map data, each of
         which has its own way of visualizing the Earth.  For example,
         repositories based on street maps typically draw roads as lines and
         "zoomed in"), and Zoom Level 15 is the lowest resolution (furthest
         from the Earth, i.e. "zoomed out").  Not all repositories are
         available at all zoom levels, and some repositories may even produce
-        an error (which you can ignore) if you try to download maps at that
-        zoom level.
+        an error (which you can usually ignore) if you try to download maps
+        at that zoom level.
       </para>
       <para>
         Once you have set up at least one repository, you can start
           Repositories dialog box to download a sample.
         </listitem>
         <listitem>
-          <display_text>Cache Dir.</display_text> - A directory on the file
+          <display_text>Cache DB</display_text> - A database file on the file
           system (either on the device's internal memory, or an external
           memory card) in which maps are stored.  Maps are kept here
-          indefinitely (until you delete them), so pick a directory with a
+          indefinitely (until you delete them), so pick a location with a
           lot of free space.  You can use the
           <display_text>Browse...</display_text> button to select the
-          directory with a graphical file system browser, or you can enter
-          the directory manually.
+          database file with a graphical file system browser, or you can enter
+          the filename manually.
         </listitem>
         <listitem>
           <display_text>Download Zoom Steps</display_text> - Controls which
           <display_text>Download Zoom Steps</display_text> ensures that you
           see all maps at their native resolution.
         </listitem>
-       <listitem>
-         <display_text>Double Pixels</display_text> - This forces Maemo
-         Mapper to avoid using the native resolution of any maps, instead
-         using pixel-doubling.  This is useful if your repository's maps
-         contain small, hard-to-read text, and you want to double the size
-         of the images to make them more readable.  This setting can also
-         affect the zoom levels that are downloaded when Auto-Download is
-         enabled.
-       </listitem>
-       <listitem>
-         <display_text>Next-able</display_text> - This oddly-named option
-         determines whether or not the "Select Next Repository" action
-         (which can be mapped to any of the hardware keys) will be able to
-         select this repository.  When unset, the "Select Next Repository"
-         action will simply skip over this repository.
-       </listitem>
+        <listitem>
+          <display_text>Double Pixels</display_text> - This forces Maemo
+          Mapper to avoid using the native resolution of any maps, instead
+          using pixel-doubling.  This is useful if your repository's maps
+          contain small, hard-to-read text, and you want to double the size
+          of the images to make them more readable.  This setting can also
+          affect the zoom levels that are downloaded when Auto-Download is
+          enabled.
+        </listitem>
+        <listitem>
+          <display_text>Next-able</display_text> - This oddly-named option
+          determines whether or not the "Select Next Repository" action
+          (which can be mapped to any of the hardware keys) will be able to
+          select this repository.  When unset, the "Select Next Repository"
+          action will simply skip over this repository.
+        </listitem>
       </list>
       <para>
         In addition to the per-repository controls, there are a few buttons
         </listitem>
         <listitem>
           <display_text>Reset...</display_text> - Resets your repository
-         list to the factory default.  This will remove all of your
-         repositories and replace them with the single default repository
-         that comes with Maemo Mapper.
+          list to the factory default.  This will remove all of your
+          repositories and replace them with the single default repository
+          that comes with Maemo Mapper.
         </listitem>
         <listitem>
           <display_text>Download...</display_text> - Downloads information
         use of a particular repository.
       </note>
     </topic>
-    <topic>
-      <topictitle>Downloading Routes</topictitle>
-      <context contextUID="help_maemomapper_downroute"/>
-      <para>
-        Route data can be loaded from GPX files, like the ones provided by
-        the GPX Driving Directions web service
-        (http://www.gnuite.com/cgi-bin/gpx.cgi).  Or, route data can be
-        downloaded directly within Maemo Mapper using the
-        <display_text>Download Route</display_text> dialog.
-      </para>
-      <para>
-        Downloading routes requires an active connection to the internet,
-        but once a route is loaded into Maemo Mapper, the internet
-        connection is no longer needed (unless
-        <display_text>Auto-Update</display_text> is enabled).  The route
-        download functionality in Maemo Mapper actually uses the
-        aforementioned GPX Driving Directions web service.
-      </para>
-      <para>
-        The <display_text>Download Route</display_text> dialog contains the
-        following controls:
-      </para>
-      <list>
-        <listitem>
-          <display_text>Source URL</display_text> - The web service from
-          which driving directions are retrieved.  The default is fine, and
-          it is usually left unchanged.
-        </listitem>
-        <listitem>
-          <display_text>Auto-Update</display_text> - This option, only
-          available if <display_text>Use GPS Location</display_text> is
-          enabled, will cause Maemo Mapper to automatically re-download a
-          new route if you stray from the route.  Note that you must have a
-          continuous connection to the internet (i.e. cellular data service)
-          for Auto-Update to work.
-        </listitem>
-        <listitem>
-          <display_text>Use GPS Location</display_text> - If selected, then
-          the current GPS location will be used as the
-          <display_text>Origin</display_text>.
-        </listitem>
-        <listitem>
-          <display_text>Use End of Route</display_text> - If selected, then
-          the end of the route will be used as the
-          <display_text>Origin</display_text>.  This is useful for stringing
-          together multiple route downloads into a single route.
-        </listitem>
-        <listitem>
-          <display_text>Origin</display_text> - If selected, then you must
-          enter your own origin.  An origin can be specified in any format
-          understood by Google Maps.  Some examples: "25, -43" (lat/lon),
-          "68712" (zip code), "San Francisco, CA", "123 Main St, 45112",
-          "5th and Main, 12151".  In fact, if your route download fails with
-          a "Could not generate directions" error message, you can use
-          Google Maps to test your origin for accuracy.
-        </listitem>
-        <listitem>
-          <display_text>Destination</display_text> - The destination to
-          which the directions will lead.  Like the
-          <display_text>Origin</display_text>, a destination can be
-          specified in any format understood by Google Maps.
-        </listitem>
-      </list>
-    </topic>
     <topic>
       <topictitle>Managing Maps</topictitle>
       <context contextUID="help_maemomapper_mapman"/>
         drawn onto the screen.  Once you have a repository set up (see 
         <ref refid="help_maemomapper_repoman"
           refdoc="Managing Repositories"/>), you can download maps from a
-        repository into a Map Cache, which is just a directory on your
+        repository into a Map Cache, which is just a database file on your
         device's file system.
       </para>
       <para>
       <para>
         Because Maemo Mapper downloads maps to your device's file system,
         you must be aware of how much disk space your maps are taking up,
-        especially if you enable Auto-Download.
+        especially if you enable Auto-Download.  If space is a concern, you
+        may also choose to go without a cache entirely.  You can do this by
+        leaving the Map Cache DB field blank in the <display_text>Manage
+        Repositories</display_text> dialog.  Note that this will cause Maemo
+        Mapper to download maps each time they are needed.  If you are using
+        a cellular data plan that charges per kilobyte, you probably want to
+        use a cache.  For more information about repositories and the
+        <display_text>Manage Repositories</display_text> dialog, see
+        <ref refid="help_maemomapper_repoman"
+          refdoc="Managing Repositories"/>.
       </para>
       <para>
         Aside from the Auto-Download functionality, you can also download
         <display_text>Go to</display_text> menu.
       </para>
     </topic>
+    <topic>
+      <topictitle>Downloading Routes</topictitle>
+      <context contextUID="help_maemomapper_downroute"/>
+      <para>
+        Route data can be loaded from GPX files, like the ones provided by
+        the GPX Driving Directions web service
+        (http://www.gnuite.com/cgi-bin/gpx.cgi).  Or, route data can be
+        downloaded directly within Maemo Mapper using the
+        <display_text>Download Route</display_text> dialog.
+      </para>
+      <para>
+        Downloading routes requires an active connection to the internet,
+        but once a route is loaded into Maemo Mapper, the internet
+        connection is no longer needed (unless
+        <display_text>Auto-Update</display_text> is enabled).  The route
+        download functionality in Maemo Mapper actually uses the
+        aforementioned GPX Driving Directions web service.
+      </para>
+      <para>
+        To download a route, you must specify an
+        <display_text>Origin</display_text> and a
+        <display_text>Destination</display_text>.  The GPX Driving
+        Directions web service will return a route taking you from the
+        origin to the destination.
+      </para>
+      <para>
+        The <display_text>Download Route</display_text> dialog contains the
+        following controls:
+      </para>
+      <list>
+        <listitem>
+          <display_text>Source URL</display_text> - The web service from
+          which driving directions are retrieved.  The default is fine, and
+          it is usually left unchanged.
+        </listitem>
+        <listitem>
+          <display_text>Auto-Update</display_text> - This option, only
+          available if <display_text>Use GPS Location</display_text> is
+          enabled, will cause Maemo Mapper to automatically re-download a
+          new route if you stray from the route.  Note that you must have a
+          continuous connection to the internet (i.e. cellular data service)
+          for Auto-Update to work.
+        </listitem>
+        <listitem>
+          <display_text>Use GPS Location</display_text> - If selected, then
+          the current GPS location will be used as the
+          <display_text>Origin</display_text>.
+        </listitem>
+        <listitem>
+          <display_text>Use End of Route</display_text> - If selected, then
+          the end of the route will be used as the
+          <display_text>Origin</display_text>.  This is useful for stringing
+          together multiple route downloads into a single route.
+        </listitem>
+        <listitem>
+          <display_text>Origin</display_text> - If selected, then you must
+          enter your own origin.  An origin can be specified in any format
+          understood by Google Maps.  Some examples: "25, -43" (lat/lon),
+          "68712" (zip code), "San Francisco, CA", "123 Main St, 45112",
+          "5th and Main, 12151".  In fact, if your route download fails with
+          a "Could not generate directions" error message, you can use
+          Google Maps to test your origin for accuracy.
+        </listitem>
+        <listitem>
+          <display_text>Destination</display_text> - The destination to
+          which the directions will lead.  Like the
+          <display_text>Origin</display_text>, a destination can be
+          specified in any format understood by Google Maps.
+        </listitem>
+      </list>
+    </topic>
+    <topic>
+      <topictitle>Downloading POIs</topictitle>
+      <context contextUID="help_maemomapper_downpoi"/>
+      <para>
+        Points of Interest (POIs) can be loaded from GPX files, like the
+        ones provided by the GPX POI Search web service
+        (http://www.gnuite.com/cgi-bin/poi.cgi).  Or, POI data can be
+        downloaded directly within Maemo Mapper using the
+        <display_text>Download POIs</display_text> dialog.
+      </para>
+      <para>
+        Downloading POIs requires an active connection to the internet,
+        but once a POI is loaded into Maemo Mapper, the POI is accessible in
+        Maemo Mapper regardless of whether or not you are connected to the
+        internet.  The POI download functionality in Maemo Mapper actually
+        uses the aforementioned GPX POI Search web service.
+      </para>
+      <para>
+        To search for POIs, you enter an <display_text>Origin</display_text>
+        and a <display_text>Query</display_text>.  The GPX POI Search web
+        service will return up to 10 matching POIs in the vicinity of the
+        origin.  You can access more POIs from the same query by using the
+        <display_text>Page</display_text> modifier.
+      </para>
+      <para>
+        Once you have downloaded POIs, they are automatically added to your
+        POI database, and you are presented with the <display_text>POI
+          List</display_text> dialog to to review the POIs that were
+        downloaded and added to your database.  You must manually remove any
+        POIs that you don't want in your database.  For more information
+        about the <display_text>POI List</display_text> dialog and
+        deleting POIs, see <ref refid="help_maemomapper_poilist"
+          refdoc="POI List"/>.
+      </para>
+      <para>
+        The <display_text>Download POIs</display_text> dialog contains the
+        following controls:
+      </para>
+      <list>
+        <listitem>
+          <display_text>Source URL</display_text> - The web service from
+          which POIs are retrieved.  The default is fine, and it is usually
+          left unchanged.
+        </listitem>
+        <listitem>
+          <display_text>Use GPS Location</display_text> - If selected, then
+          the current GPS location will be used as the
+          <display_text>Origin</display_text>.
+        </listitem>
+        <listitem>
+          <display_text>Use End of Route</display_text> - If selected, then
+          the end of the route will be used as the
+          <display_text>Origin</display_text>.  This is useful for searching
+          for points of interests (like hotels or restaurants) near your
+          current destination.
+        </listitem>
+        <listitem>
+          <display_text>Origin</display_text> - If selected, then you must
+          enter your own origin.  An origin can be specified in any format
+          understood by Google Maps.  Some examples: "25, -43" (lat/lon),
+          "68712" (zip code), "San Francisco, CA", "123 Main St, 45112",
+          "5th and Main, 12151".  In fact, if your route download fails with
+          a "Could not generate directions" error message, you can use
+          Google Maps to test your origin for accuracy.
+        </listitem>
+        <listitem>
+          <display_text>Category</display_text> - Specifies the default
+          category in which all resulting POIs will be placed.  You can
+          always change the category later.  If you have not yet entered a
+          <display_text>Query</display_text> when you select a category,
+          then the name of the category will be entered into the
+          <display_text>Query</display_text> field for you.  This allows you
+          to, for example, quickly search for restaurants and put them in
+          the Restaurant category.
+        </listitem>
+        <listitem>
+          <display_text>Page</display_text> - Specifies the page of results
+          that you want to retrieve.  Think of it as the page number in a
+          web search.  Page 1 contains the first 10 results.  Page 2
+          contains results 10-19.  And so on.
+        </listitem>
+        <listitem>
+          <display_text>Query</display_text> - A free-form text query that
+          describes the POIs for which you are searching.  This can be
+          anything from "food" to "hairstylist" to "museum."  Note that the
+          selected <display_text>Category</display_text> is not part of the
+          query unless you explicitly include it in the
+          <display_text>Query</display_text> field.
+        </listitem>
+      </list>
+    </topic>
+    <topic>
+      <topictitle>Browsing POIs</topictitle>
+      <context contextUID="help_maemomapper_browsepoi"/>
+      <para>
+        Once you have imported or downloaded POIs into your POI database,
+        you can use the <display_text>Browse POIs</display_text> dialog to
+        search for certain POIs in your database and to view those POIs in a
+        tabular format.
+      </para>
+      <para>
+        To browse for POIs, you enter an <display_text>Origin</display_text>
+        and a optional <display_text>Query</display_text>.  Maemo Mapper
+        will search the database for all POIs matching your query, and it
+        will calculate the distance from each POI to your specified
+        <display_text>Origin</display_text>.  You may also filter your
+        results by <display_text>Category</display_text>.
+      </para>
+      <para>
+        Once your search is performed, you are taken to the
+        <display_text>POI List</display_text> dialog, where you can view,
+        edit, and delete any of the POIs that matched your query.  For more
+        information about the <display_text>POI List</display_text> dialog
+        and editing POIs, see <ref refid="help_maemomapper_poilist"
+          refdoc="POI List"/>.
+      </para>
+      <para>
+        The <display_text>Browse POIs</display_text> dialog contains the
+        following controls:
+      </para>
+      <list>
+        <listitem>
+          <display_text>Use GPS Location</display_text> - If selected, then
+          the current GPS location will be used as the
+          <display_text>Origin</display_text>.
+        </listitem>
+        <listitem>
+          <display_text>Use End of Route</display_text> - If selected, then
+          the end of the route will be used as the
+          <display_text>Origin</display_text>.  This is useful for searching
+          for points of interests (like hotels or restaurants) near your
+          current destination.
+        </listitem>
+        <listitem>
+          <display_text>Origin</display_text> - If selected, then you must
+          enter your own origin.  An origin can be specified in any format
+          understood by Google Maps.  Some examples: "25, -43" (lat/lon),
+          "68712" (zip code), "San Francisco, CA", "123 Main St, 45112",
+          "5th and Main, 12151".  In fact, if your route download fails with
+          a "Could not generate directions" error message, you can use
+          Google Maps to test your origin for accuracy.
+        </listitem>
+        <listitem>
+          <display_text>Category</display_text> - Filters the results based
+          on the selected category.
+        </listitem>
+        <listitem>
+          <display_text>Query</display_text> - An optional substring which
+          must appear in either the label or description of a POI in order
+          for the POI to match.  Any spaces, commas, or other punctiation in
+          the query must also be in the label or description.  If left
+          blank, then all POIs are matched.
+        </listitem>
+      </list>
+    </topic>
+    <topic>
+      <topictitle>POI List</topictitle>
+      <context contextUID="help_maemomapper_poilist"/>
+      <para>
+        The <display_text>POI List</display_text> dialog is a tabular
+        display of POIs.  With this dialog, you can go to a specific POI,
+        edit POIs, change the categories of a set of POIs, delete POIs, and
+        export POIs to the GPX file format.
+      </para>
+      <para>
+        The main view of the <display_text>POI List</display_text> dialog is
+        a table with five columns, all of which (except the checkbox) can be
+        sorted by tapping on the appropriate header:
+      </para>
+      <list>
+        <listitem>
+          <display_text>*</display_text> - This checkbox column contains a
+          checkbox for each POI in the table.  All of the POIs that are
+          checked will be affected by operations in the
+          <display_text>Checked POI Actions</display_text> dialog, described
+          later.  You can tap on the column header to enable or disable
+          all of the checkboxes at once.  Note that this checkbox has no
+          effect on whether or not the POI is visible in the map.
+        </listitem>
+        <listitem>
+          <display_text>Category</display_text> - The category in which the
+          POI belongs.  Categories can be edited, enabled, and disabled with
+          the <display_text>POI Categories</display_text> dialog.  For more
+          information about the <display_text>POI Categories</display_text>
+          dialog, see <ref refid="help_maemomapper_poicat"
+            refdoc="POI Categories"/>
+        </listitem>
+        <listitem>
+          <display_text>Dist.</display_text> - The distance from the Origin
+          to the given POI.
+        </listitem>
+        <listitem>
+          <display_text>Bear.</display_text> - The bearing (in degrees from
+          true north) from the Origin to the given POI.  A bearing of zero
+          or 360 means that the POI is due north of the Origin.  90 means
+          east; 180 means south; and 270 means west.
+        </listitem>
+        <listitem>
+          <display_text>Label</display_text> - The label of the POI.
+        </listitem>
+      </list>
+      <para>
+        Below the table are four buttons:
+      </para>
+      <list>
+        <listitem>
+          <display_text>Go to</display_text> - Pans the map display to the
+          currently selected POI (i.e. the currently highlighted row).
+          Remember that you can tap and hold on the title bar of the dialog
+          in order to see the map behind it.
+        </listitem>
+        <listitem>
+          <display_text>Edit...</display_text> - Opens the
+          <display_text>Edit POI</display_text> dialog for the currently
+          selected POI (i.e. the currently highlighted row).  You can also
+          double-tap on a row in the table to open this dialog.
+        </listitem>
+        <listitem>
+          <display_text>Checked POI Actions...</display_text> - Opens the
+          <display_text>Checked POI Actions</display_text> dialog, which
+          allows you to perform actions on the currently checked POIs in the
+          table.  From that dialog, you can set the categories of the
+          checked POIs, delete the checked POIs, and/or export the checked
+          POIs to a GPX file.
+        </listitem>
+        <listitem>
+          <display_text>Close</display_text> - Closes the <display_text>POI
+            List</display_text> dialog.
+        </listitem>
+      </list>
+    </topic>
     <topic>
       <topictitle>POI Categories</topictitle>
       <context contextUID="help_maemomapper_poicat"/>
       <para>
         The <display_text>Settings</display_text> dialog (accessible from
         the main menu) provides access to a plethora of configurable options
-       that control how Maemo Mapper appears and runs.  In addition to the
-       tabs, which are described below, there are also two buttons at the
-       bottom of the diagram labeled <display_text>Hardware
-         Keys...</display_text> and <display_text>Colors...</display_text>.
+        that control how Maemo Mapper appears and runs.  In addition to the
+        tabs, which are described below, there are also two buttons at the
+        bottom of the diagram labeled <display_text>Hardware
+          Keys...</display_text> and <display_text>Colors...</display_text>.
       </para>
       <para>
-       The <display_text>Hardware Keys...</display_text> button brings up
-       another dialog box, which allows you to customize the actions that
-       each hardware key causes.  For example, you can map the 
+        The <display_text>Hardware Keys...</display_text> button brings up
+        another dialog box, which allows you to customize the actions that
+        each hardware key causes.  For example, you can map the 
         <graphic filename="2686KEY_esc"/> button to cycle through map
-       repositories, giving you quick access to switching among them.
+        repositories, giving you quick access to switching among them.
       </para>
       <para>
         The <display_text>Colors...</display_text> button allows you to
           mark, all tracks and routes, and the default POI image.
         </listitem>
         <listitem>
-          <display_text>Keep Display On Only in Fullscreen
-            Mode</display_text> - Controls whether or not Maemo Mapper
-          should limit its "Keep the display on" behavior to full screen
-          mode only.  If disabled, then Maemo Mapper will always keep the
-          screen on, as long as you are moving.  If enabled, Maemo Mapper
-          will only keep the screen on in full screen mode.
+          <display_text>Unblank Screen</display_text> - Controls when Maemo
+          Mapper keeps the display on without user input.  When set to
+          <display_text>When Receiving Any GPS Data</display_text>, Maemo
+          Mapper will keep the screen on whenever a GPS receiver is
+          connected and producing data.  When set to
+          <display_text>Never</display_text>, Maemo Mapper will not attempt
+          to keep the screen on, and the screen will go blank after a period
+          of inactivity on the user's part.  The default is
+          <display_text>When Moving (Full Screen Only)</display_text>
         </listitem>
         <listitem>
-          <display_text>Information Font Size</display_text> - Controls the
-          font size for all information that is popped up to the user in the
+          <display_text>Info Font Size</display_text> - Controls the font
+          size for all information that is popped up to the user in the
           upper-right corner, including waypoint descriptions.
         </listitem>
         <listitem>
           <display_text>Degrees Format</display_text> - Controls how
           latitude and longitudes are displayed in the user interface.
         </listitem>
+        <listitem>
+          <display_text>Auto-Download Pre-cache</display_text> - Controls
+          how much of the world surrounding the view Maemo Mapper should
+          download when <display_text>Auto-Download</display_text> is
+          enabled.  When set to the minimum, Maemo Mapper will only download
+          the maps that are required to draw the screen.  As you pan around
+          the world, you will see black areas where Maemo Mapper has not yet
+          downloaded maps, until those maps are downloaded.  If you increase
+          the Pre-cache amount, the Maemo Mapper will download more of the
+          surrounding areas, making it less likely that you ever actually
+          see black areas.  A general rule of thumb is to limit the
+          Pre-cache based on the bandwidth of your internet connection, but
+          the default setting (two bars) is usually sufficient for most
+          people's needs.
+        </listitem>
         <listitem>
           <display_text>Speed Limit</display_text> - Enables notification
           when you have exceeded the given speed limit (specified in the
-          units defined via the <display_text>Units</display_text> option.
+          units defined via the <display_text>Units</display_text> option).
         </listitem>
         <listitem>
           <display_text>Location</display_text> - Controls the location on
       </para>
       <para>
         Maemo Mapper was created and developed by John Costigan (aka
-       <display_text>gnuite</display_text>).
+        <display_text>gnuite</display_text>).
       </para>
       <para>
         Copyright © 2006-2007 John Costigan.
         POI and GPS-Info code originally written by Cezary Jackiewicz.
       </para>
       <para>
-       Default map data provided by http://www.openstreetmap.org/ - other
-       map repositories are subject to their own licenses and may or may not
-       be suitable for use with Maemo Mapper.  It may be illegal to use a
-       certain repository with Maemo Mapper or under certain conditions.  This
-       includes the repositories downloadable directly in Maemo Mapper.  If
-       you are not sure if you are legally allowed to use a particular
-       repository, you should delete it from your list of repositories.  The
-       authors of Maemo Mapper cannot be held responsible for your use of a
-       particular repository.
-      </para>
-      <para>
-        This program is free software; you can redistribute it and/or modify
-        it under the terms of the GNU General Public License as published by
-        the Free Software Foundation; either version 2 of the License, or
-        (at your option) any later version.
+        Default map data provided by http://www.openstreetmap.org/ - other
+        map repositories are subject to their own licenses and may or may not
+        be suitable for use with Maemo Mapper.  It may be illegal to use a
+        certain repository with Maemo Mapper or under certain conditions.  This
+        includes the repositories downloadable directly in Maemo Mapper.  If
+        you are not sure if you are legally allowed to use a particular
+        repository, you should delete it from your list of repositories.  The
+        authors of Maemo Mapper cannot be held responsible for your use of a
+        particular repository.
       </para>
       <para>
-        This program is distributed in the hope that it will be useful,
-        but WITHOUT ANY WARRANTY; without even the implied warranty of
-        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-        GNU General Public License for more details.
+        Maemo Mapper is free software: you can redistribute it and/or modify it
+        under the terms of the GNU General Public License as published by the
+        Free Software Foundation, either version 3 of the License, or (at your
+        option) any later version.
       </para>
       <para>
-        You should have received a copy of the GNU General Public License along
-        with this program; if not, write to the Free Software Foundation, Inc.,
-        51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+        Maemo Mapper is distributed in the hope that it will be useful, but
+        WITHOUT ANY WARRANTY; without even the implied warranty of
+        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+        General Public License for more details.
       </para>
     </topic>
   </folder>
diff --git a/data/help/fi_FI/maemomapper.xml.in b/data/help/fi_FI/maemomapper.xml.in
new file mode 100644 (file)
index 0000000..2c83ab4
--- /dev/null
@@ -0,0 +1,1257 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ossohelpsource>
+  <folder>
+    <title>Maemo Mapper</title>
+    <topic>
+      <topictitle>Esittely</topictitle>
+      <context contextUID="help_maemomapper_intro"/>
+      <para>Tervetuloa Maemo Mapperiin.</para>
+      <para>
+        Maemo Mapper on maantieteellinen karttatyökalu, jota voidaan käyttää
+        seuraavasti:
+      </para>
+      <list>
+        <listitem>
+          Karttojen lataamiseen laitteen sisäiseen muistiin tai erilliselle
+          muistikortille.
+        </listitem>
+        <listitem>
+          Ladattujen karttojen näyttämiseen näytöllä.
+        </listitem>
+        <listitem>
+          Ladattujen karttojen vapaaseen selailuun näytöllä useilla eri
+          zoom tasoilla.
+        </listitem>
+        <listitem>
+          Sijainnin ja muiden GPS:n tietojen näyttämiseen GPS-
+          vastaanottimelta.
+        </listitem>
+        <listitem>
+          Point-of-Interest (POI) kohteiden näyttämiseen.
+        </listitem>
+        <listitem>
+          Reittisuunnitelmien lataamiseen vapaavalintaisten pisteiden 
+         välille.
+        </listitem>
+        <listitem>
+          Reittisuunnitelmien ja reittijälkien tallentamiseen ja avaamiseen.
+        </listitem>
+      </list>
+      <para>
+        Käytä <ref refid="help_maemomapper_" refdoc="sisältö"/> sivua
+        siirtyäksesi ohjeen eri osa-alueisiin tai siirry <ref 
+          refid="help_maemomapper_getstarted" refdoc="aloitusohje"/> 
+        sivulle päästäksesi nopeasti alkuun.
+      </para>
+    </topic>
+    <topic>
+      <topictitle>Aloitusohje</topictitle>
+      <context contextUID="help_maemomapper_getstarted"/>
+      <para>
+        Kun Maemo Mapper käynnistetään ensimmäistä kertaa, sinulle näytetään
+        <display_text>Asetukset</display_text> valintaikkuna.  Suurimmalle
+        osalle asetuksista on toimivat oletusasetukset, mutta jos sinulla on
+        bluetooth GPS-vastaanotin, niin sen MAC-osoite kannattaa syöttää
+        <display_text>MAC</display_text> kenttään.  Mikäli et tiedä
+        GPS-vastaanottimesi MAC-osoitetta, niin laita se päälle ja kosketa
+        <display_text>Etsi</display_text> nappia.  Maemo Mapper yrittää
+        tällöin etsiä automaattisesti GPS-vastaanottimesi MAC-osoitteen.
+        <display_text>Asetukset</display_text> valintaikkunan tarkemmat tiedot
+        löytyvät <ref refid="help_maemomapper_settings" 
+          refdoc="Asetukset"/> ohjeesta.
+      </para>
+      <para>
+        Kun olet muuttanut asetukset haluamiksesi voit jatkaa koskettamalla
+        <display_text>Ok</display_text> nappia.  Tämä avaa
+        <display_text>Karttavarastojen hallinta</display_text> 
+        valintaikkunan.
+      </para>
+      <para>
+        Nopein tapa ottaa karttavarastot käyttöön on koskettaa
+        <display_text>Lataa...</display_text> nappia, jolloin Maemo
+        Mapper hakee käyttöösi listan esimääriteltyjä karttavarastoja.
+        Jos otat esimääritellyt karttavarastot käyttöön, voit halutessasi
+        poistaa <display_text>Default</display_text> karttavaraston. 
+        Tarkemmat tiedot <display_text>Karttavarastojen
+        hallinta</display_text> valintaikkunan valintoihin löytyvät
+        <ref refid="help_maemomapper_repoman"
+          refdoc="Karttavarastojen hallinta"/> ohjeesta.
+      </para>
+      <para>
+        Tietyt karttavarastot (yleensä kaupalliset) saattavat sisältää
+        niiden käyttöön liittyvän lisenssisopimuksen.  Joissakin tilanteissa
+        tällaisten karttavarastojen käyttäminen saattaa olla lisenssiehtojen
+        vastaista.  Myös <display_text>Lataa...</display_text> napilla
+        haetut karttavarastot saattavat sisältää tällaisen lisenssisopimuksen.
+        Mikäli et ole varma onko jonkin karttavaraston käyttö karttojen
+        tarjoajan lisenssiehtojen mukaista, niin sinun tulisi poistaa se
+        käytössä olevien karttavarastojen listalta.  Karttavarastojen käyttö on
+        jokaisen omalla vastuulla.
+      </para>
+      <para>
+        Kun olet ottanut haluamasi karttavarastot käyttöön, kosketa Ok
+        nappia.  Tämän jälkeen eteesi ilmestyy tyhjä ruutu.  Tämä johtuu
+        siitä, että et ole vielä ladannut karttoja laitteen muistiin.
+        Ottaaksesi automaattisen karttojen lataamisen käyttöön, valitse
+        päävalikosta <display_text>Kartat</display_text> > 
+        <display_text>Autom. noutaminen</display_text>.
+      </para>
+      <para>
+        Mikäli sinulla on toimiva internet yhteys laitteessasi, Maemo Mapper
+        yrittää nyt ladata karttoja.  Onnistuneen latauksen jälkeen ladatut
+        kartat näytetään ruudulla automaattisesti ja ensimmäisenä sinun tulisi 
+        nähdä maailmankartta.  Ole varovainen karttojen automaattisen noutamisen
+        kanssa, koska se saattaa täyttää nopeasti käytettävissä olevan
+        tallennustilan.  Tarkemmat tiedot levytilan hallintaan löytyy
+        <ref refid="help_maemomapper_mapman" refdoc="Karttojen hallinta"/>
+        ohjeesta.
+      </para>
+      <heading>Graafinen käyttöliittymä</heading>
+      <para>
+        Maemo Mapperin päänäkymä korostaa yksinkertaista suunnittelua.
+        Oletusasetuksilla kartta on ainoa näkyvissä oleva asia.  Sijainti
+        näytetään sinisellä ympyrällä silloin, kun GPS-vastaanotin on käytössä.
+        Sinisestä ympyrästä loittoneva viiva kuvaa sen hetken etenemissuuntaa
+        ja nopeutta.  <i>Reittijälki</i> näytetään punaisella värillä ja se
+        kertoo missä olet liikkunut.  <i>Reittisuunnitelma</i> näytetään
+        vihreällä värillä ja sillä ilmaistaan mihin haluat mennä, esim.
+        reittiopasteet johonkin tiettyyn kohteeseen.
+      </para>
+      <para>
+        Laitteen valintanäppäimiä voidaan käyttää eri toimintojen nopeaan 
+        valitsemiseen:
+      </para>
+      <list>
+        <listitem>
+          <graphic filename="2686KEY_full_screen"/> - Koko näyttö 
+          päälle/pois
+        </listitem>
+        <listitem>
+          <graphic filename="2686KEY_zoom_in"/> - Tarkenna - pidä pohjassa
+          siirtyäksesi useita zoom-tasoja kerrallaan
+        </listitem>
+        <listitem>
+          <graphic filename="2686KEY_zoom_out"/> - Loitonna - pidä pohjassa
+          siirtyäksesi useita zoom-tasoja kerrallaan
+        </listitem>
+        <listitem>
+          <graphic filename="2686KEY_scroll_up"/> - Siirry pohjoiseen - pidä
+          pohjassa vierittääksesi
+        </listitem>
+        <listitem>
+          <graphic filename="2686KEY_scroll_down"/> - Siirry etelään - pidä 
+          pohjassa vierittääksesi
+        </listitem>
+        <listitem>
+          <graphic filename="2686KEY_scroll_left"/> - Siirry länteen - pidä
+          pohjassa vierittääksesi
+        </listitem>
+        <listitem>
+          <graphic filename="2686KEY_scroll_right"/> - Siirry itään - pidä
+          pohjassa vierittääksesi
+        </listitem>
+        <listitem>
+          <graphic filename="2686KEY_scroll_center"/> - Valitse
+          <ref refid="Auto-Center" refdoc="Automaattinen keskitys"/>
+        </listitem>
+        <listitem>
+          <graphic filename="2686KEY_esc"/> - Ohjelmoitavissa; oletuksena
+          reittijäljet päällä/pois
+        </listitem>
+      </list>
+      <para>
+        Voit myös liikkua ympäri karttaa koskettamalla näyttöä, jolloin
+        Maemo Mapper keskittää näytön kosketuskohtaan.  Mikäli
+        <display_text>Automaattinen keskitys</display_text> toiminne oli
+        päällä, niin se poistetaan automaattisesti käytöstä.
+      </para>
+      <para>
+        Tästä eteenpäin voit käyttää valikkoja reittisuunnitelmien,
+       reittijälkien ja karttojen hallintaan; näkymän vaihtoon; asetusten
+       muuttamiseen; tai yksityiskohtaisten GPS-tietojen näyttämiseen
+       silloin, kun GPS-vastaanotin on käytössä.
+      </para>
+      <para>
+        Ohjelmassa on lisäksi asiayhteyteen liittyvä valikko, joka ilmestyy
+        kartalle sen jälkeen, kun jotain kohtaa kartalla kosketetaan
+        pidempään.  Tästä valikosta voidaan ladata reittisuunnitelmia, laskea
+        etäisyyksiä tai lisätä ja poistaa Point-of-Interest (POI) kohteita.
+      </para>
+      <para>
+        Yllämainittujen ominaisuuksien käyttöohjeet löytyvät
+        <ref refid="help_maemomapper_" refdoc="sisältö"/> sivulta.
+      </para>
+    </topic>
+    <topic>
+      <topictitle>Päävalikko</topictitle>
+      <context contextUID="help_maemomapper_mainmenu"/>
+      <para>
+        Tässä ohjeen aiheessa kuvataan Maemo Mapperin päävalikon valintojen
+        toiminta.
+      </para>
+      <heading>Reittisuunnitelma</heading>
+      <para>
+        <display_text>Reittisuunnitelma</display_text> valikkoa käytetään
+        <i>reittisuunnitelman</i> hallintaan.  Reittisuunnitelma määritellään
+        Maemo Mapperissa reittipisteillä ja kohdepisteillä, kuvaten sitä
+        <i>mihin haluat mennä</i>. Esimerkiksi ajo-ohjeet 123 Main Streetiltä
+        456 Elm Streetille.  Käytössä oleva reittisuunnitelma voi koostua
+        useista        eri osista.  Reittisuunnitelmaa ei ole käytössä ennen 
+        olemassa olevan suunnitelman avaamista tai Internetistä lataamista.
+      </para>
+      <para>
+        <display_text>Reittisuunnitelma</display_text> valikossa on
+        seuraavat kohdat:
+      </para>
+      <list>
+        <listitem>
+          <display_text>Avaa...</display_text> - Avaa reittisuunnitelman
+         laitteen muistissa olevasta GPX-tiedostosta.  Avattu
+         reittisuunnitelma <i>lisätään</i> käytössä olevaan reittiin, joten
+         voit liittää eri reitisuunnitelmia yhteen mikäli haluat luoda
+         reittisuunnitelman useisiin eri kohteisiin.
+        </listitem>
+        <listitem>
+          <display_text>Lataa...</display_text> - Lataa reittisuunnitelman
+         Internetistä.  Katso <ref refid="help_maemomapper_downroute"
+            refdoc="Reittisuunnitelman lataaminen"/> ohjeesta lisätietoja.
+        </listitem>
+        <listitem>
+          <display_text>Tallenna...</display_text> - Tallentaa käytössäolevan
+          reittisuunnitelman GPX-tiedostona laitteen muistiin.
+        </listitem>
+        <listitem>
+          <display_text>Näytä etäisyys seur. kohdepisteeseen</display_text>
+          - Näyttää jäljellä olevan matkan seuraavaan kohdepisteeseen reittiä
+          pitkin kuljettaessa.
+        </listitem>
+        <listitem>
+          <display_text>Näytä etäisyys reitin loppupisteeseen</display_text>
+         - Näyttää jäljellä olevan matkan käytössä olevan reittisuunnitelman
+          päätepisteeseen.  Laskettu etäisyys sisältää myös etäisyyden reitissä
+          olevien katkosten välillä (esim. kahden erillisen reittisegmentin
+          välillä).
+        </listitem>
+        <listitem>
+          <display_text>Nollaa</display_text> - Nollaa Maemo Mapperin
+          reitinseurannan.  Valitse tämä, mikäli Maemo Mapper hukkaa sijaintisi
+         reittisuunnitelman ollessa käytössä.
+        </listitem>
+        <listitem>
+          <display_text>Tyhjennä</display_text> - Tyhjennä käytössä oleva
+         reittisuunnitelma, korvaamalla se tyhjällä reitillä.
+        </listitem>
+      </list>
+      <heading>Reittijälki</heading>
+      <para>
+        <display_text>Reittijälki</display_text> valikkoa käytetään näytöllä
+        olevan <i>reittijäljen</i> hallintaan.  Reittijälki muodostuu Maemo 
+       Mapperissa kuljetun reitin varrelta otetuista näytteistä, sen mukaan
+       <i>missä olet liikkunut</i>.  Reittijälki voi muodostua useista eri
+        segmenteistä ja se on kaikkein hyödyllisin, mikäli käytössä on
+        GPS-vastaanotin.  Näytössä oleva reittijälki on tyhjä, kunnes GPS antaa
+        vähintään yhden oikean paikkatiedon.  Reittijäljen piste lisätään näytölle
+        vasta sen jälkeen, kun olet siirtynyt riittävän etäälle edellisestä
+        reittijäljen pisteestä.
+      </para>
+      <para>
+        <display_text>Reittijälki</display_text> valikossa on seuraavat
+       kohdat:
+      </para>
+      <list>
+        <listitem>
+          <display_text>Avaa...</display_text> - Avaa reittijäljen laitteen
+         muistissa olevasta GPX-tiedostosta.  Erona reittisuunnitelmaan
+         avattu reittijälki <i>liitetään</i> kiinni käytössä olevaan
+          reittijälkeen.  Mikäli yrität muodostaa uudelleen aiempaa
+          reittijälkeä, sinun täytyy avata reittijäljet ajallisesti oikeassa
+          järjestyksessä (uusin reittijälki ensin).
+        </listitem>
+        <listitem>
+          <display_text>Tallenna...</display_text> - Tallentaa nykyisen
+         reittijäljen GPX-tiedostoksi laitteen muistiin.
+        </listitem>
+        <listitem>
+          <display_text>Lisää katkaisupiste</display_text> - Lisätään 
+         keinotekoinen katkaisupiste nykyiseen reittijälkeen.  
+          Katkaisupisteellä simuloidaan GPS-signaalin kadottamista ja 
+         uudelleen lukittumista.  Käyttökohde voi olla esimerkiksi 
+         tankaamaan pysähtymisen merkitseminen.
+        </listitem>
+        <listitem>
+          <display_text>Lisää merkki</display_text> - Lisätään kuvauksen
+          sisältävä merkki nykyiseen reittijälkeen.  Tällä tavalla voidaan merkitä
+          esimerkiksi tärkeitä maamerkkejä.
+        </listitem>
+        <listitem>
+          <display_text>Näytä etäisyys katkaisupisteestä</display_text>
+         - Näyttää reittiä pitkin kuljetun etäisyyden edellisestä
+          katkaisupisteestä nykyiseen sijaintiin.
+        </listitem>
+        <listitem>
+          <display_text>Näytä etäisyys lähtöpisteestä</display_text> -
+         Näyttää lähtöpisteestä reittiä pitkin kuljetun matkan nykyiseen 
+         sijaintiin.  Laskettu matka sisältää katkaisupisteiden välisen
+         etäisyyden (esim. GPS-signaalin kadottamisen ja uudelleen
+         lukittumisen luomat välit).
+        </listitem>
+        <listitem>
+          <display_text>Tyhjennä</display_text> - Tyhjentää käytössä olevan 
+         reittijäljen.
+        </listitem>
+      </list>
+      <heading>Kartat</heading>
+      <para>
+        <display_text>Kartat</display_text> valikkoa käytetään karttojen
+        hallintaan.  Tähän valikkoon lisätään kaikki määritetyt karttavarastot ja
+        listalta voidaan valita käytössä oleva karttavarasto.
+      </para>
+      <para>
+        <display_text>Kartat</display_text> valikko sisältää karttavarastojen
+        lisäksi seuraavat kohdat:
+      </para>
+      <list>
+        <listitem>
+          <display_text>Karttojen hallinta</display_text> - Lataa tai
+         poistaa karttoja käytössä olevasta karttavarastosta.  Tarkemmat
+         ohjeet löytyvät <ref refid="help_maemomapper_mapman"
+           refdoc="Karttojen hallinta"/> ohjeesta.
+        </listitem>
+        <listitem>
+          <display_text>Karttavarastojen hallinta...</display_text> -
+         Käytössolevien karttavarastojen hallinta ja uusien lisääminen.  
+         Voit myös ladata listan esimääriteltyjä karttavarastoja. Tarkemmat
+         ohjeet löytyy <ref refid="help_maemomapper_repoman"
+           refdoc="Karttavarastojen hallinta"/> ohjeesta.
+        </listitem>
+        <listitem>
+          <display_text>Autom. noutaminen</display_text> - Ottaa käyttöön
+         tai poistaa käytöstä Maemo Mapperin automaattisen karttojen lataamisen.
+          Kun tämä kohta on valittuna kartat ladataan automaattisesti, kun sopivaa
+          karttaa ei löydy laitteen muistista. Tämä on hyödyllinen ominaisuus
+          aktiivisen internet yhteyden (WLAN tai kännykän datayhteys) kanssa esim.
+          silloin, kun tutkitaan maailman eri kolkkia.
+        </listitem>
+      </list>
+      <heading>Näytä</heading>
+      <para>
+        <display_text>Näytä</display_text> valikko mahdollistaa niiden
+        tietojen valitsemisen, mitlä näytetään ja mitä ei näytetä näytöllä.
+      </para>
+      <para>
+        <display_text>Näytä</display_text> valikossa on valittavissa seuraavat
+        kohdat:
+      </para>
+      <list>
+        <listitem>
+         <display_text>Tarkenna</display_text> - Zoomaa karttaa yhden
+         zoom tason tarkemmaksi.  Valintaan voidaan käyttää myös 
+         <graphic filename="2686KEY_zoom_in"/> näppäintä.
+        </listitem>
+        <listitem>
+         <display_text>Loitonna</display_text> - Zoomaa karttaa yhden zoom
+         tason epätarkemmaksi.  Valintaan voidaan käyttää myös
+         <graphic filename="2686KEY_zoom_out"/> näppäintä.
+        </listitem>
+        <listitem>
+          <display_text>Koko näyttö</display_text> - Kytkee koko näyttö tilan
+         päälle tai pois. Koko näytön valintaan voidaan käyttää myös
+           <graphic filename="2686KEY_full_screen"/> näppäintä.
+        </listitem>
+        <listitem>
+          <display_text>Reittisuunnitelma</display_text> - Kytkee 
+         reitisuunitelman näytön päälle tai pois.
+        </listitem>
+        <listitem>
+          <display_text>Reittijälki</display_text> - Kytkee reittijäljen
+         näytön päälle tai pois.
+        </listitem>
+        <listitem>
+          <display_text>Nopeusvektori</display_text> - Kytkee nopeusvektorin
+         päälle tai pois.  Nopeusvektori on sininen viiva, joka loittonee
+         sijaintia osoittavasta ympyrästä.
+        </listitem>
+        <listitem>
+          <display_text>POI:t</display_text> - POI-kohteiden näyttö päälle tai
+          pois.
+        </listitem>
+        <listitem>
+          <display_text>POI-kategoriat...</display_text> - Määritellään
+          POI-kohteiden kategoriat ja mitkä niistä näytetään kartalla.  Tarkemmat
+          ohjeet löytyvät <ref refid="help_maemomapper_poicat"
+           refdoc="POI-Kategoriat"/> ohjeesta.
+        </listitem>
+      </list>
+      <heading>Autom. keskitys</heading>
+      <para>
+        <display_text>Autom. keskitys</display_text> valikkoa käytetään
+       kartan automaattiseen vierittämiseen liittyviin asetuksiin.  Kattaa
+       voidaan vierittää automaattisesti sijainnin muuttuessa.  Sijainnin
+       muutokseen liittyvää keskityksen herkkyyttä voidaan säätää
+       <ref refid="help_maemomapper_settings" refdoc="Asetukset"/> 
+       valikosta. Herkkyydellä voidaan vaikuttaa siihen, kuinka lähelle
+       reunaa sijainti saa mennä ennen automaattista keskitystä.
+      </para>
+      <para>
+        Automaattiselle keskitykselle on valittavissa kolme erilaista
+       tapaa: 
+      </para>
+      <list>
+        <listitem>
+          <display_text>Lat/Lon</display_text> - Pitää sijainnin aina
+         keskellä ruutua.
+        </listitem>
+        <listitem>
+          <display_text>Etumatka</display_text> - Nopeudesta riippuva
+         asetus, joka keskittää kartan automaattisesti sen hetkisestä
+         sijainnista eteenpäin.  Suuremmalla nopeudella liikuttaessa karttaa
+         keskitetään kauemmaksi eteen.
+        </listitem>
+        <listitem>
+          <display_text>Ei keskitystä</display_text> - Karttaa ei keskitetä 
+         automaattisesti.
+        </listitem>
+      </list>
+      <heading>Siirry</heading>
+      <para>
+        <display_text>Siirry</display_text> valikkoa käytetään kartan
+       keskittämiseen haluttuun sijaintiin.
+      </para>
+      <para>
+        <display_text>Siirry</display_text> valikossa on seuraavat kohdat:
+      </para>
+      <list>
+        <listitem>
+          <display_text>Lat/Lon...</display_text> - Voidaan määritellä
+         tarkka latitudi ja longitudi, mihin kartta keskitetään.
+        </listitem>
+        <listitem>
+          <display_text>GPS-sijainti</display_text> - Keskittää kartan
+         senhetkiseen GPS-sijaintiin. Tämä valinta on manuaalinen vastine
+         yllämainitulle <display_text>Autom. keskitys</display_text>
+         toiminteelle.
+        </listitem>
+        <listitem>
+          <display_text>Seuraava kohdepiste</display_text> - Keskittää
+         kartan seuraavaan kohdepisteeseen käytössä olevalla reitillä.  
+         Oletuksena seuraava reitin kohdepiste on hieman tummempi,
+         kuin muut kohdepisteet. 
+        </listitem>
+        <listitem>
+          <display_text>Lähin POI</display_text> - Keskittää kartan
+         lähimpään POI-pisteeseen.
+        </listitem>
+      </list>
+      <heading>GPS</heading>
+      <para>
+        <display_text>GPS</display_text>-valikkoa käytetään
+        GPS-vastaanottimeen liittyvien asioiden hallintaan, sisältäen niiden
+       tietojen näytön mitä ei näytetä kartalla.  Valikosta valitaan myös
+       onko GPS-vastaanotin käytössä vai ei.
+      </para>
+      <list>
+        <listitem>
+          <display_text>Käytä GPS:ää</display_text> - Kytkee yhteyden
+          GPS-vastaanottimeen päälle tai pois päältä.  GPS-vastaanotin pitää
+         olla määriteltynä valinnan onnistumiseksi.  Kun valinta on päällä,
+         Maemo Mapper etsii jatkuvasti asetuksissa määriteltyä GPS-vastaanotinta.
+        </listitem>
+        <listitem>
+          <display_text>Näytä tietoja</display_text> - Näyttää 
+          GPS-vastaanottimen antamia lisätietoja näytöllä.  Tiedot näytetään
+          pääikkunan vasemmassa alalaidassa olevassa paneelissa.
+        </listitem>
+        <listitem>
+          <display_text>Yksityiskohdat...</display_text> - Näyttää
+         yksityiskohtaiset tiedot GPS-vastaanottimelta, sisältäen mm.
+         näkyvissä olevien satelliittien sijainnin maahan nähden.
+        </listitem>
+        <listitem>
+          <display_text>Nollaa bluetooth</display_text> - Yrittää nollata
+         laitteen bluetooth radion mikäli se on mennyt jumiin.  Jotta
+         radion nollaus olisi mahdollista, seuraava rivi <i>täytyy</i>
+         lisätä /etc/sudoers tiedostoon (jos et tiedä mitä se tarkoittaa,
+         niin älä edes kokeile muokkausta):  
+         <b>user ALL = NOPASSWD: /usr/sbin/hciconfig hci0 reset</b>
+        </listitem>
+      </list>
+      <heading>Muut</heading>
+      <para>
+        Edellä mainittujen valikkojen lisäksi päävalikossa on muutamia muita
+       kohteita:
+      </para>
+      <list>
+        <listitem>
+          <display_text>Asetukset...</display_text> - Maemo Mapperin
+         asetusten tarkistaminen ja muuttaminen.  Tarkemmat ohjeet
+         asetusten muuttamiseen löytyy
+         <ref refid="help_maemomapper_settings" refdoc="Asetukset"/> 
+         ohjeesta.
+        </listitem>
+        <listitem>
+          <display_text>Ohje...</display_text> - Avaa tämän ohjetiedoston.
+        </listitem>
+        <listitem>
+          <display_text>Tietoja...</display_text> - Näyttää ohjelman 
+         versiotiedot ja tekijänoikeudet.
+        </listitem>
+        <listitem>
+          <display_text>Sulje</display_text> - Lopettaa Maemo Mapperin
+         käytön.
+        </listitem>
+      </list>
+    </topic>
+    <topic>
+      <topictitle>Asiayhteysvalikko</topictitle>
+      <context contextUID="help_maemomapper_cmenu"/>
+      <para>
+        Koskettamalla ja pitämällä kosketusnäytön kohtaa pohjassa, avautuu
+       asiayhteyskohtainen valikko joko sijaintiin, lähimpään reitin
+       kohdepisteeseen tai lähimpään POI-pisteeseen liittyen.
+      </para>
+      <para>
+        Asiayhteysvalikko on jaettu kahteen hierarkkiseen tasoon.
+       Ensimmäisellä tasolla (<display_text>Sijainti</display_text>,
+        <display_text>Kohdepiste</display_text> tai
+        <display_text>POI</display_text>) määritellään millaiseen tietoon
+       mikäkin toiminto vaikuttaa.
+      </para>
+      <heading>Sijainti</heading>
+      <para>
+        <display_text>Sijainti</display_text> valikossa olevat toiminnot
+       tapahtuvat juuri siihen pisteeseen kartalla, mistä valikko on avattu.
+       Tähän sijaintiin liittyen on mahdollista tehdä seuraavia toimenpiteitä:
+      </para>
+      <list>
+        <listitem>
+          <display_text>Näytä Lat/Lon</display_text> - Näyttää kyseisen
+         pisteen latitudin ja longitudin siinä muodossa, jossa ne on
+         <display_text>Asetukset</display_text> valintaikkunassa määritetty
+         näytettäväksi.
+        </listitem>
+        <listitem>
+          <display_text>Kopioi Lat/Lon</display_text> - Kopioi kyseisen
+         pisteen latitudin ja longitudin leikepöydälle, pilkuilla erotetussa
+         desimaali muodossa.
+        </listitem>
+        <listitem>
+          <display_text>Näytä etäisyys kohteeseen</display_text> - Näyttää
+         suoraa viivaa pitkin olevan matkan GPS:n sijainnista valittuun
+          kohteeseen.
+        </listitem>
+        <listitem>
+          <display_text>Lataa reittisuunnitelma kohteeseen...</display_text>
+         - Avaa <ref refid="help_maemomapper_downroute"
+            refdoc="Reittisuunnitelman lataaminen"/> valintaikkunan, 
+          jossa kosketuskohdan sijainti on määritetty valmiiksi
+          reittisuunnitelman kohdepisteeksi.
+        </listitem>
+        <listitem>
+          <display_text>Lisää reittipiste</display_text> - Lisää
+         kosketuskohdan sijainnin käytössä olevaan reittisuunnitelmaan.
+         Tämä merkki ei ole reitin kohdepiste.
+        </listitem>
+        <listitem>
+          <display_text>Lisää kohdepiste...</display_text> - Lisää
+         kohdepisteen käytössä olevaan reittisuunnitelmaan. Kohdepisteelle
+         pitää antaa kuvaus, jotta se voidaan lisätä reittisuunnitelmaan.
+         Mikäli kuvausta ei anneta, tehdään reittisuunnitelmaan
+         katkaisukohta.  Tätä katkaisukohtaa ei kytketä vanhaan
+          reittisuunnitelmaan, joten sitä voidaan käyttää uuden segmentin
+         aloituspisteenä.
+        </listitem>
+        <listitem>
+          <display_text>Lisää POI...</display_text> - Lisää valitun kohdan
+         sijainnin POI-pisteenä POI-tietokantaan.  Jos kategoria mihin
+          lisäsit POI-pisteen ei ole käytössä, pistettä ei näytetä kartalla,
+          vaan se lisätään pelkästään POI-tietokantaan.
+        </listitem>
+        <listitem>
+          <display_text>Aseta GPS-sijainniksi</display_text> - Pakottaa Maemo
+          Mapperin valitsemaan kyseisen kohdan GPS-sijainniksi.  Tämä ei
+         vaikuta nykyiseen reittijälkeen, mutta se muuttaa sijaintia
+         kuvaavan sinisen ympyrän kyseiseen pisteeseen. Tätä pistettä
+         voidaan sitten käyttää täten reittisuunnitelman alkupisteenä.
+        </listitem>
+      </list>
+      <heading>Kohdepiste</heading>
+      <para>
+        <display_text>Kohdepiste</display_text> valikossa olevilla
+       valinnoilla voidaan vaikuttaa kosketuskohtaa lähinnä olevaan
+       reittisuunnitelman kohdepisteeseen.  Mikäli kohdepisteitä ei ole
+       kosketuskohdan lähellä, näytetään virheilmoitus.
+      </para>
+      <list>
+        <listitem>
+          <display_text>Näytä Lat/Lon</display_text> - Näyttää lähimmän
+         kohdepisteen latitudin ja longitudin siinä muodossa, jossa ne on
+         <display_text>Asetukset</display_text> valintaikkunassa määritetty
+         näytettäväksi.
+        </listitem>
+        <listitem>
+          <display_text>Näytä kuvaus</display_text> - Näyttää lähimmän
+         kohdepisteen kuvauksen.  Kun reittisuunnitelma ladataan
+         <ref refid="help_maemomapper_downroute" 
+            refdoc="Reittisuunnitelman lataaminen"/>
+         valintaikkunasta, kohdepisteiden kuvaus sisältää kuvauksen miten ko.
+         kohdepiste saavutetaan. Esimerkiksi "Turn left at Main Street.  Go 2.5
+         kilometers.").
+        </listitem>
+        <listitem>
+          <display_text>Kopioi Lat/Lon</display_text> - Kopioi lähimmän
+         kohdepisteen latitudin ja longitudin leikepöydälle pilkuilla
+         erotetussa desimaali muodossa.
+        </listitem>
+        <listitem>
+          <display_text>Kopioi kuvaus</display_text> - Kopioi lähimmän 
+         kohdepisteen kuvauksen leikepöydälle.
+        </listitem>
+        <listitem>
+          <display_text>Näytä etäisyys kohteeseen</display_text> - Näyttää
+         jäljellä olevan matkan (käytössä olevaa reittisuunnitelmaa pitkin
+         kuljettaessa) kyseiseen kohdepisteeseen.  Laskettu matka sisältää
+         katkosten välisen etäisyyden (esim. kahden eri reittisuunnitelman
+         loppu- ja alkupisteen välit). 
+        </listitem>
+        <listitem>
+          <display_text>Lataa reitti kohteeseen...</display_text> - Avaa
+          <ref refid="help_maemomapper_downroute"
+            refdoc="Reittisuunnitelman lataaminen"/> valintaikkunan, jossa
+          kosketuskohdan lähimmän kohdepisteen sijainti on määritetty valmiiksi
+          reittisuunnitelman kohdepisteeksi.
+        </listitem>
+        <listitem>
+          <display_text>Poista...</display_text> - Poistaa kosketuskohtaa
+         lähinnä olevan kohdepisteen reittisuunnitelmasta. Tämä poistaa
+         kaikki reittisegmentit kohdepisteen ympäriltä, sisältäen (ja
+         rajoittuen) kaikki pisteet tästä kohdepisteestä seuraavaan ja
+         edelliseen kohdepisteeseen.
+        </listitem>
+        <listitem>
+          <display_text>Lisää POI...</display_text> - Lisää valitun kohdan
+         sijainnin kohdepisteen POI-pisteenä POI-tietokantaan. Jos kategoria
+         mihin lisäsit POI-pisteen ei ole käytössä, pistettä ei näytetä
+         kartalla, vaan se lisätään pelkästään POI-tietokantaan.
+        </listitem>
+      </list>
+      <heading>POI</heading>
+      <para>
+        <display_text>POI</display_text>-valikossa voidaan vaikuttaa
+       kosketuskohtaa lähinnä olevan POI:n tietoihin. Mikäli kosketuskohdan
+       lähellä ei ole POI-pisteitä näytetään virheilmoitus.
+      </para>
+      <list>
+        <listitem>
+          <display_text>Näytä/Muokkaa...</display_text> - Näytä ja/tai
+         muokkaa valittua POI-pistettä.
+        </listitem>
+        <listitem>
+          <display_text>Näytä etäisyys kohteeseen</display_text> - Näyttää
+         suoraa linjaa pitkin etäisyyden GPS-sijainnista kyseiseen POI 
+         -pisteeseen.
+        </listitem>
+        <listitem>
+          <display_text>Lataa reitti kohteeseen...</display_text> - Avaa
+          <ref refid="help_maemomapper_downroute"
+            refdoc="Reittisuunnitelman lataaminen"/> valintaikkunan, jossa
+          kosketuskohdan lähimmän POI-pisteen sijainti on määritetty valmiiksi
+          reittisuunnitelman kohdepisteeksi.
+        </listitem>
+        <listitem>
+          <display_text>Lisää reittipiste</display_text> - Lisää nykyiseen
+         reittisuunnitelmaan merkin, jossa sijaintina käytetään
+         kosketuskohtaa lähinnä olevaa POI-pistettä. Tämä merkki ei ole
+         reittisuunnitelman kohdepiste.
+        </listitem>
+        <listitem>
+          <display_text>Lisää kohdepiste...</display_text> - Lisää
+         kosketuskohtaa lähinnä olevan POI-pisteen sijainnin kohdepisteeksi
+         käytössä olevaan reittisuunnitelmaan. Kohdepisteelle pitää antaa
+         kuvaus, jotta se voidaan lisätä reittisuunnitelmaan. Mikäli
+         kuvausta ei anneta, tehdään reittisuunnitelmaan katkaisukohta.
+         Tätä katkaisukohtaa ei kytketä vanhaan reittisuunnitelmaan, joten
+         sitä voidaan käyttää uuden segmentin aloituspisteenä.
+        </listitem>
+      </list>
+    </topic>
+    <topic>
+      <topictitle>Karttavarastojen hallinta</topictitle>
+      <context contextUID="help_maemomapper_repoman"/>
+      <para>
+        Maemo Mapperissa kartat on jaettu erityisiin osastoihin, joita
+       kutsutaan <i>karttavarastoiksi</i>.  Karttavarastot toimivat karttojen
+       lähteenä ja jokaisella karttavarastolla on omanlaisensa tapa kuvata
+       maapalloa.  Esimerkiksi karttavarasto, joka sisältää tiekartat, esittää
+       tiet viivoina ja rakennukset alueina, kun taas satelliittikuviin
+       perustuvat karttavarastot esittävät maan sillä tavalla, miltä maa
+       näyttää avaruudesta katsottuna.  Lisäksi on niin sanottuja "hybridi"
+       karttavarastoja, jotka näyttävät tiekartat satelliitista otettujen
+       kuvien päällä.  Myös topografisia karttavarastoja on olemassa, jolloin
+       kartassa näytetään myös korkeustieto.
+      </para>
+      <para>
+        Jokainen karttavarasto luodaan kuudellatoista, eri zoom tasolla
+       olevasta kartta-aineistosta.  Zoom taso 0 on tarkin (lähinnä maata)
+       ja zoom taso 15 on epätarkin (kauimpana maasta).  Kaikki
+       karttavarastot eivät sisällä kaikkia zoom tasoja, jolloin
+       karttavarastot ilmoittavat puuttuvasta kartta-aineistosta
+       virheilmoituksella.
+      </para>
+      <para>
+        Kun Maemo Mapperiin on asetettu vähintään yksi karttavarasto,
+       karttojen lataus tästä karttavarastosta laitteen muistiin tai
+       muistikortille voidaan aloittaa. Yksityiskohtaiset ohjeet
+       karttavarastojen lisäämiseksi löytyy <ref refid="help_maemomapper_mapman"
+         refdoc="Karttojen hallinta"/> ohjeesta.
+      </para>
+      <para>
+        Maemo Mapperiin voidaan lisätä useita karttavarastoja, mutta vain
+        yksi niistä voi olla käytössä kerrallaan.  
+       <display_text>Karttavarastojen hallinta</display_text> valintaikkunaan
+       päästään, valitsemalla päävalikosta <display_text>Kartat</display_text>
+        > <display_text>Karttavarastojen hallinta...</display_text>, 
+       jolloin karttavarastoja voidaan lisätä, muokata tai poistaa.
+      </para>
+      <para>
+        <display_text>Karttavarastojen hallinta...</display_text> sisältää 
+        pudotuslistan, josta valitaan näytettävä ja muokattava karttavarasto.
+        Kun karttavarasto on valittuna, näytössä näkyy käytössä olevat asetukset
+        ja ne voidaan muuttaa halutuiksi:
+      </para>
+      <list>
+        <listitem>
+          <display_text>URL:n muotoilu</display_text> - Tietyllä tavalla
+          muotoiltu tekstijono, joka näyttää URL:ta, mutta sen tulee sisältää
+          vähintään yksi printf-tyylinen korvaava merkkijono (kuten %f tai %s).
+          Yleensä oikeat URL:t tulee etsiä Internetistä    
+          (www.internettablettalk.com on hyvä lähde).  Koskettamalla
+          <display_text>Lataa...</display_text> nappia karttavarastojen
+          hallinta näkymässä, voidaan ladata esimerkki URL:t automaattisesti.
+        </listitem>
+        <listitem>
+          <display_text>Tallennuskansio</display_text> - Kansio laitteen
+          tiedostojärjestelmässä (joko sisäisessä muistissa tai muistikortilla)
+          mihin kartat tallennetaan.  Kartat säilytetään tässä kansiossa, eikä
+          niitä poisteta automaattisesti. Tästä syystä on hyvä valita kansio,
+          jossa on paljon vapaata tilaa. Käytettävä kansio voidaan valita
+          koskettamalla <display_text>Selaa</display_text> nappia, tai kansion
+          polku voidaan kirjoittaa valintaikkunaan käsin.
+        </listitem>
+        <listitem>
+          <display_text>Lataa zoom tasot</display_text> - Valinnalla
+          määritellään mitkä zoom tasot ohitetaan käytettäessä automaattista
+          karttojen latausta (Autom. noutaminen valittuna kartat valikossa).
+          Pienin valinta (yksi palkki) valittuna haetaan kaikki zoom tasot ja
+          suurin valinta (neljä palkkia) valittuna ladataan joka neljäs zoom
+          taso (0, 4, 8, 12, 16).
+        </listitem>
+        <listitem>
+          <display_text>Näytä zoom tasot</display_text> - Samantapainen
+          ylläkuvatun <display_text>Lataa zoom tasot</display_text> kanssa,
+          mutta tämä valinta määrittelee kuinka Maemo Mapper käyttäytyy
+          zoomatessa karttaa. Esimerkiksi kaksi palkkia valittuna
+          <graphic filename="2686KEY_zoom_in"/> näppäimen painaminen zoomaa
+          karttaa kaksi tasoa yhden sijaan.  Asettamalla tämä samaan arvoon
+          <display_text>Lataa zoom tasot</display_text> kanssa, näytetään kaikki
+          kartat alkuperäisellä resoluutiolla.
+        </listitem>
+       <listitem>
+         <display_text>Tuplapikselit</display_text> - Tämä pakottaa Maemo
+         Mapperin välttämään alkuperäistä resoluutiota, jolloin kaikki kartat
+          näytetään kaksinkertaiseksi suurennettuna.  Tämä valinta on
+          käytännöllinen silloin, kun karttavaraston kartat sisältävät paljon
+          pientä ja vaikealukuista tekstiä.  Tämä asetus voi vaikuttaa myös
+          ladattaviin zoom tasoihin silloin, kun automaattinen karttojen
+          noutaminen on valittuna.
+       </listitem>
+       <listitem>
+         <display_text>Pikavalittava</display_text> - Tämä valinta määrittelee
+          miten "Valitse seuraava karttavarasto" toiminta kohtelee kyseistä
+          karttavarastoa. (toiminto voidaan valita mihin tahansa laitteen
+          näppäimeen).  Mikäli valintaruutu jätetään tyhjäksi, "Valitse seuraava
+          karttavarasto" toiminto yksinkertaisesti ohittaa kyseisen
+          karttavaraston.
+       </listitem>
+      </list>
+      <para>
+        Karttavarastokohtaisten valintojen lisäksi sivulla on muutama näppäin,
+        jotka toteuttavat seuraavat toiminnallisuudet:
+      </para>
+      <list>
+        <listitem>
+          <display_text>Nimeä uud...</display_text> - Muuttaa valitun
+          karttavaraston nimen.
+        </listitem>
+        <listitem>
+          <display_text>Poista...</display_text> - Poistaa valitun
+          karttavaraston.
+        </listitem>
+        <listitem>
+          <display_text>Uusi...</display_text> - Lisää uuden karttavaraston.
+        </listitem>
+        <listitem>
+          <display_text>Nollaa...</display_text> - Asettaa karttavarastolistan
+          oletusasetukset.  Tämä valinta poistaa kaikki karttavarastot ja korvaa
+          ne Maemo Mapperin oletusasetuksella.
+        </listitem>
+        <listitem>
+          <display_text>Lataa...</display_text> - Lataa listan esimääriteltyjä
+          karttavarastoja ja lisää ne käytössä olevien karttavarastojen listaan.  
+          Ladatut karttavarastot lisätään olemassa olevien joukkoon.  Nämä
+          karttavarastot ovat samalla tavalla muokattavissa ja poistettavissa, 
+          kuin itse määritellyt.  Tämä on hyvä tapa päästä alkuun.
+        </listitem>
+      </list>
+      <note>
+        Osa karttavarastoista (erityisesti kaupalliset) saattavat sisältää
+        käyttöön liittyviä lisenssiehtoja.  Joissakin tilanteissa sellaisten
+        karttavarastojen käyttö saattaa olla lisenssiehtojen vastaista.  Myös
+        <display_text>Lataa...</display_text> napilla haetut karttavarastot
+        saattavat sisältää edellä mainitun kaltaisia rajoitteita.  Mikäli et ole
+        varma onko jonkin karttavaraston käyttö lisenssiehtojen mukaista, niin
+        sinun tulisi poistaa se käytössä olevien listalta. Karttavarastojen
+        käyttö on jokaisen omalla vastuulla.
+      </note>
+    </topic>
+    <topic>
+      <topictitle>Reittisuunnitelman lataaminen</topictitle>
+      <context contextUID="help_maemomapper_downroute"/>
+      <para>
+        Reittitiedot voidaan ladata GPX-tiedostoista ja niitä on mahdollista
+        luoda käyttämällä Internetissä olevaa GPX-reittisuunnitelma palvelua
+        (http://www.gnuite.com/cgi-bin/gpx.cgi).  Vaihtoehtoisesti
+        reittisuunnitelma voidaan ladata suoraan Maemo Mapperista käyttämällä
+        <display_text>Lataa reittisuunnitelma</display_text> valintaikkunaa.
+      </para>
+      <para>
+        Reittisuunnitelman lataaminen vaatii aktiivisen Internet yhteyden. Kun
+        reittisuunnitelma on ladattu Internet yhteyttä ei enää tarvita (ellei
+        karttojen <display_text>Autom. noutaminen</display_text> ole valittuna).
+        Reittisuunnitelman lataus ominaisuus käyttää edellä mainittua 
+        GPX-reittisuunnitelmapalvelua.
+      </para>
+      <para>
+        <display_text>Lataa reittisuunnitelma</display_text> valintaikkuna
+        sisältää seuraavat valinnat:
+      </para>
+      <list>
+        <listitem>
+          <display_text>Lähde URL</display_text> - Internet palvelu, mistä 
+          reittisuunnitelma ladataan.  Oletusasetuksella pärjää hyvin, eikä
+          sen muuttamiseen ole yleensä tarvetta.
+        </listitem>
+        <listitem>
+          <display_text>Autom. päivitys</display_text> - Tämä on valittavissa
+          vain silloin, kun <display_text>Käytä GPS-sijaintia</display_text>
+          -valinta on valittuna. Valinta mahdollistaa uuden reittisuunnitelman
+          lataamisen, jos reittisuunnitelmasta on ajauduttu sivuun. Käytettäessä
+          automaattista päivitystä tulee Internet yhteyden olla käytössä (esim.
+          matkapuhelimen datayheys), tai uuden reittisuunnitelman noutaminen ei
+          onnistu.
+        </listitem>
+        <listitem>
+          <display_text>Käytä GPS sijaintia</display_text> - Jos valittuna,
+          käytetään sen hetkistä GPS-sijaintia reitin
+          <display_text>lähtöpisteenä</display_text>.
+        </listitem>
+        <listitem>
+          <display_text>Käytä reitin loppupistettä</display_text> - Jos
+          valittuna, käytetään edellisen reittisuunnitelman loppupistettä uuden
+          <display_text>lähtöpisteenä</display_text>.  Tämä ominaisuus on
+          hyödyllinen, kun halutaan luoda useasta reitistä muodostuva
+          kokonaisuus.
+        </listitem>
+        <listitem>
+          <display_text>Lähtöpiste</display_text> - Jos valittuna, käyttäjän 
+          pitää syöttää oma lähtöpiste.  Lähtöpiste voidaan määritellä
+          missä tahansa Google Mapsin ymmärtämistä muodoista.  Joitakin
+          esimerkkejä: "25, -43" (lat/lon), "68712" (postinumero), "San
+          Francisco, CA", "123 Main St, 45112","5th and Main, 12151",
+          "Kauppakatu 22, Jyväskylä"  Mikäli reittisuunnitelman lataaminen
+          epäonnistuu ja Maemo Mapper antaa virheilmoituksen "Ei voitu luoda
+          reittisuunnitelmaa", kannattaa kokeilla käytettyä lähdepistettä
+          Google Maps palvelussa.
+        </listitem>
+        <listitem>
+          <display_text>Kohdepiste</display_text> - Kohde, mihin
+          reittisuunnitelma ohjaa.  Kuten
+          <display_text>Lähtöpiste</display_text>, kohdepiste annetaan Google
+          Mapsin ymmärtämässä muodossa.
+        </listitem>
+      </list>
+    </topic>
+    <topic>
+      <topictitle>Karttojen hallinta</topictitle>
+      <context contextUID="help_maemomapper_mapman"/>
+      <para>
+        Maemo Mapperissa, <i>karttavarastoilla</i> määritellään karttadatan
+        lähteet. Itse <i>kartat</i> ovat tavallisia kuvatiedostoja (esim. PNG
+        tai JPEG), mitkä esitetään näytöllä.  Kun karttavarasto on määritetty
+        käyttöön (katso <ref refid="help_maemomapper_repoman"
+          refdoc="Karttavarastojen hallinta"/>), karttoja voidaan ladata
+        laitteen sisäiseen muistiin tai muistikortille.
+      </para>
+      <para>
+        Maemo Mapper lataa kartat käytössä olevasta karttavarastosta 
+        laitteen pysyvään muistiin siten, että kartat voidaa esittää
+        näytöllä myöhemmin, ilman karttojen uudelleen lataamista.
+      </para>
+      <para>
+        Koska Maemo Mapper lataa kartat laitteen pysyvään muistiin, kannattaa
+        olla tarkkana karttojen lataamisessa, sillä kartat saattavat täyttää
+        käytetyn muistin hyvinkin nopeasti.  Tämä vaara on olemassa erityisesti
+        silloin, kun karttojen automaattinen noutaminen on käytössä.
+      </para>
+      <para>
+        Kartat voidaan ladata myös manuaalisesti, valitsemlla
+        <display_text>Kartat</display_text> valikosta
+        <display_text>Karttojen hallinta...</display_text>.
+        <display_text>Karttojen hallinta</display_text> valintaikkuna
+        mahdollistaa karttojen lataamisen, ylikirjoituksen tai poiston, joko
+        tietyltä alueelta tai reittisuunnitelman varrelta.  Valintaikkuna
+        sisältää kolme välilehteä, joilla määritellään miltä alueelta ja
+        kuinka monta karttaa ladataan.
+      </para>
+      <heading>Valinnat</heading>
+      <para>
+        <display_text>Valinnat</display_text> välilehdellä valitaan mitä
+        tehdään.  Karttoja voidaan ladata (myös ylikirjoittamalla jo ladatut
+        kartat) käytössä olevasta karttavarastosta laitteen muistiin.  Karttoja
+        voidaan myös poistaa laitteen muistista (valittuna olevasta
+        karttavarastosta).  Molemmat näistä toiminnoista voidaan tehdä joko
+        suorakulmion muotoiselle alueelle tai reitin
+        mukaan.
+      </para>
+      <list>
+        <listitem>
+          <display_text>Lataa kartat</display_text> - Jos valittuna, Maemo
+          Mapper lataa kartat käytössä olevasta karttavarastosta laitteen 
+          muistiin, käyttäjän määrittelemältä alueelta. Oletuksena, Maemo
+          Mapper lataa vain ne kartat, mitä laitteen muistiin ei ole ladattu.
+        </listitem>
+        <listitem>
+          <display_text>Ylikirjoita</display_text> - Jos valittuna, Maemo
+          Mapper lataa kartat käyttäjän määrittelemältä alueelta ja
+          ylikirjoittaa laitteen muistista löytyvät kyseisen alueen kartat.
+        </listitem>
+        <listitem>
+          <display_text>Poista kartat</display_text> - Jos valittuna, Maemo
+          Mapper poistaa valitun alueen kartat laitteen muistista.
+        </listitem>
+        <listitem>
+          <display_text>Alueelta</display_text> - Jos valittuna, Maemo Mapper
+          lataa tai poistaa kartat avoinna olevan näkymän vasemman yläkulman ja
+          oikean alakulman koordinaattien mukaiselta alueelta.  Kooordinaatit 
+          voidaan määrittää myös käsin <display_text>Alue</display_text>
+          välilehdellä.
+        </listitem>
+        <listitem>
+          <display_text>Reitin varrelta</display_text> - Jos valittuna, Maemo
+          Mapper lataa tai poistaa kartat avoinna olevan reittisuunnitelman
+          varrelta.  Tämä ominaisuus on hyödyllinen esimerkiksi silloin, kun
+          käyttäjä haluaa varmistaa, että kaikki reittisuunnitelman varrella
+          olevat kartat löytyvät laitteen muistista.
+        </listitem>
+        <listitem>
+          <display_text>Säde</display_text> - Jos
+          <display_text>Reitin varrelta</display_text> on valittuna, käyttäjä
+          voi määritellä säteen minkä mukaan kartat ladataan tai poistetaan. 
+          Esimerkiksi, jos valittuna on 4 (oletus asetus), niin Maemo Mapper
+          lataa kaikki kartan palat, jotka ovat 4 päässä reittisuunnitelmasta.
+        </listitem>
+      </list>
+      <heading>Zoom tasot</heading>
+      <para>
+        <display_text>Zoom tasot</display_text> välilehdellä määritellän minkä
+        zoom tason kartat ladataan tai poistetaan.  Käytössä oleva zoom taso on 
+        valittuna oletuksena, mutta voit valita ne zoom tasot mitkä haluat.
+      </para>
+      <heading>Alue</heading>
+      <para>
+        <display_text>Alue</display_text> välilehti on valittavissa, mikäli
+        <display_text>Valinnat</display_text> välilehdellä on
+        <display_text>Alueelta</display_text> kohta valittuna.  Alue määrittelee
+        suorakaiteen muotoisen alueen, minkä mukaan kartat ladataan tai
+        poistetaan.  Jos mahdollista, kentät on esitäytetty nykyisen ja
+        edellisen ruudun keskipisteiden koordinaateilla.  Tämä mahdollistaa
+        halutun alueen valinnan keskittämällä kartta ensin suorakulman yhteen
+        kulmaan ja sitten toiseen.  Keskitys tapahtuu koskettamalla haluttuja
+        kohtia näytöllä tai koskettamalla <display_text>Siirry</display_text>
+        valikosta <display_text>Lat/Lon</display_text> valinta ja antamalla
+        avautuvaan valintaikkunaan halutun pisteen koordinaatit.
+      </para>
+    </topic>
+    <topic>
+      <topictitle>POI-kategoriat</topictitle>
+      <context contextUID="help_maemomapper_poicat"/>
+      <para>
+        Tämä valintaruutu mahdollistaa haluttujen POI-kategorioiden
+        organisoinnin, näyttämisen, lisäyksen, poiston ja muokkaamisen.
+        Valintaikkuna avataan valitsemalla
+        <display_text>Näytä</display_text> >
+        <display_text>POI-kategoriat...</display_text>
+        Maemo Mapperin päävalikosta.
+      </para>
+      <para>
+        Jokainen rivi taulukossa kuvaa yhtä kategoriaa ja jokaiselle
+        kategorialle on kolme saraketta:
+      </para>
+      <list>
+        <listitem>
+          <display_text>Käytössä</display_text> - Määrittelee näytetäänkö
+          kyseisen kategorian POI-pisteet kartalla.
+        </listitem>
+        <listitem>
+          <display_text>Nimike</display_text> - Lyhyt nimi, jolla kuvataan
+          kategoriaa.  Tämä nimi näkyy, kun POI-pistettä tarkastellaan.
+        </listitem>
+        <listitem>
+          <display_text>Kuvaus</display_text> - Pidempi kuvaus kategoriasta.
+          Tämä kuvaus on näkyvissä ainoastaan tässä valintaikkunassa ja sen
+          tarkoitus on antaa kuva siitä, mihin kategoriaa on tarkoitus käyttää.
+        </listitem>
+      </list>
+      <para>
+        Valitsemalla haluttu rivi taulukosta ja koskettamalla
+        <display_text>Muokkaa</display_text> nappia, voidaan kaikkia kyseisen
+        kategorian tietoja muokata ja kategoria voidaan myös poistaa.  Uusia
+        kategorioita voidaan lisätä koskettamalla
+        <display_text>Lisää</display_text> nappia.
+      </para>
+      <note>
+        POI-piste voi kuulua ainoastaan yhteen kategoriaan kerrallaan.
+      </note>
+    </topic>
+    <topic>
+      <topictitle>Asetukset</topictitle>
+      <context contextUID="help_maemomapper_settings"/>
+      <para>
+        <display_text>Asetukset</display_text>-valikko (avattavissa
+        päävalikosta) tarjoaa runsaasti eri asetusvaihtoehtoja, joilla
+        määritellään miltä Maemo Mapper näyttää ja miten se toimii.  Seuraavaksi
+        kuvattavien välilehtien lisäksi, asetukset valintaikkunassa on kaksi
+        nappia, joiden nimi on <display_text>Näppäimet...</display_text> ja 
+        <display_text>Värit...</display_text>.
+      </para>
+      <para>
+       <display_text>Näppäimet...</display_text> nappi avaa uuden valintaikkunan,
+       jossa voidaan asettaa mitä mikin laitenäppäin tekee sitä painettaessa. 
+        Esimerkiksi <graphic filename="2686KEY_esc"/> näppäin voidaan määritellä
+        valitsemaan uusi karttavarasto.
+      </para>
+      <para>
+        <display_text>Värit...</display_text> nappi mahdollistaa kartalla
+        näkyvien objektien värien muuttamisen halutuiksi.
+      </para>
+      <heading>GPS</heading>
+      <para>
+        <display_text>GPS</display_text>-välilehti kertoo Maemo Mapperille
+        bluetooth laitteen, miltä GPS-paikkatieto on saatavissa. Tämä valinta
+        on käytettävissä Maemo Mapperin kanssa vain, jos sinulla on bluetooth
+        yhteensopiva GPS-vastaanotin.
+      </para>
+      <para>
+        GPS-vastaanottimen bluetooth MAC-osoite tulee syöttää MAC-kenttään.
+        Mikäli et tiedä vastaanottimesi MAC-osoitetta, kytke vastaanotin päälle
+        ja kosketa <display_text>Etsi...</display_text> nappia, jolloin Maemo
+        Mapper etsii lähellä olevat bluetooth laittet.
+      </para>
+      <para>
+        <i>Vaihtoehtoisesti</i>, mikäli käytät rfcomm tai jotain muuta
+        tiedostojärjestelmäpohjaista NMEA syötettä lähteenä, voit syöttää
+        kenttään lähteen polun. Polku voisi olla esimerkiksi (alkaa aina
+        vino viivalla) "/dev/rfcomm1".  Tässä tapauksessa Maemo Mapper
+        lukee NMEA lauseet tiedostojärjestelmästä bluetoothin sijaan.
+      </para>
+      <heading>Automaattinen keskitys</heading>
+      <para>
+        <display_text>Autom. keskitys</display_text> välilehti antaa sinulle
+        mahdollisuuden muuttaa kartan automaattisen keskityksen asetuksia.
+        Maemo Mapper keskittää kartan automaattisesti, kun 
+        <display_text>Lat/Lon</display_text> tai
+        <display_text>Etumatka</display_text> on valittuna päävalikon
+        <display_text>Autom. keskitys</display_text> valikosta.  Automaattinen
+        keskitys valinnasta on hyötyä ainoastaan käytettäessä GPS-vastaanotinta.
+      </para>
+      <list>
+        <listitem>
+          <display_text>Herkkyys</display_text> - Määrittää kuinka usein
+          Maemo Mapper keskittää kartan, perustuen siihen kuinka lähelle
+          sijaintisi (tai edessä olevan pisteen, kun <i>etumatka</i> on 
+          valittuna) menee näytön reunaa.  Kun asetus on pienimmillään, Maemo
+          Mapper keskittää kartan vasta sijainnin ollessa näytön laidalla.  
+          Asetuksen ollessa maksimissaan, Maemo Mapper pyrkii pitämään sijainnin
+          mahdollisimman lähellä näytön keskustaa.
+        </listitem>
+        <listitem>
+          <display_text>Etumatkan määrä</display_text> - Kun
+          <display_text>Etumatka</display_text> on valittuna, Maemo Mapper
+          pitää näytön keskittettynä sijaintisi eteen.  Liikkuessasi
+          tämä valinta näyttää karttaa etupainotteisesti, jolloin sinun on 
+          mahdollista nähdä tulevat tiet ajoissa.  Keskityspisteen etäisyyden
+          laskemiseen käytetään kahta muuttujaa: keskityshetken nopeus ja 
+          <display_text>Etumatkan määrä</display_text> valinnan arvo.
+        </listitem>
+      </list>
+      <heading>Ilmoitus</heading>
+      <para>
+        <display_text>Ilmoitus</display_text> välilehti ohjaa, miten
+        ja milloin Maemo Mapper näyttää tai puhuu kohdepisteen tiedot.  
+        Lähestyessäsi reittisuunnitelman kohdepistettä (määritettynä 
+        GPX-tiedoston kuvauksessa), Maemo Mapper näyttää tekstivalikon
+        kyseisellä sisällöllä.  Kun reittisuunnitelma on ladattu Maemo
+        Mapperilla, teksti näyttää seuraavan ajo-ohjeen, esim. "Turn left at
+        Kauppakatu.  Go 0.1 kilometers."
+      </para>
+      <para>
+        Mennessäsi lähemmäksi kohdepistettä, Maemo Mapper näyttää pisteen
+        kuvausta niin kauan, kunnes saavut 
+        <display_text>Ennakkovaroitus</display_text> valinnan rajojen
+        sisäpuolelle, tai ohitat kohdepisteen.  Koska ilmoitushetki riippuu
+        nopeudestasi, ilmoitusteksti saattaa poistua pysähtyessäsi esimerkiksi
+        liikennevaloihin.  Ilmoitusteksti ilmaantuu uudestaan, kun vauhti on
+        lisääntynyt sen verran, että saavut uudelleen
+        <display_text>Ennakkovaroitus</display_text> valinnan rajojen sisälle. 
+      </para>
+      <para>
+        Mikäli olet asentanut <i>fliten</i> (saatavissa Maemo Mapperin kanssa
+        samasta sovellusluettelosta), niin Maemo Mapper voi halutessasi puhua
+        samat ohjeet, mitä se näyttää näytöllä.  Ohjeet puhutaan ainoastaan
+        yhden kerran, ja se tapahtuu silloin kun saavut ensimmäistä kertaa
+        <display_text>Ennakkovaroitus</display_text> valinnan rajojen
+        sisäpuolelle.  Sama tieto on luettavissa näytöltä, mikäli haluat
+        varmistaa ohjeen tiedot.
+      </para>
+      <list>
+        <listitem>
+          <display_text>Ennakkovaroitus</display_text> - Määrittää kuinka
+          paljon ennen kohdepistettä Maemo Mapper antaa ensimmäisen ilmoituksen
+          kohdepisteen kuvauksesta.  Tarkka etäisyys missä ilmoitus annetaan
+          riippuu myös nopeudestasi, joten tämän asetuksen arvon oppii tietämään
+          parhaiten ajan myötä.  Arvon ollessa pienimmillään, Maemo Mapper
+          antaa ilmoituksen juuri ennen kohdepisteeseen saapumista.  Asetuksen
+          ollessa maksimissaan, Maemo Mapper antaa ilmoituksen noin kaksi minuuttia
+          ennen kohdepisteeseen saapumista.  Itselle parhaiten sopivan arvon
+          löytää ainoastaan kokeilemalla.
+        </listitem>
+        <listitem>
+          <display_text>Käytä puhesyntetisaattoria</display_text> - Jos
+          <i>flite</i> on asennettuna, valitsemalla tämän valintaruudun
+          Maemo Mapper puhuu kohdepisteen kuvauksen saapuessasi 
+          <display_text>Ennakkovaroitus</display_text> valinan rajojen sisälle.
+        </listitem>
+      </list>
+      <heading>Sekal.</heading>
+      <para>
+        <display_text>Sekal.</display_text> ja
+        <display_text>Sekal. 2</display_text> välilehdet sisältävät sekalaisia
+        valintoja.
+      </para>
+      <list>
+        <listitem>
+          <display_text>Viivan leveys</display_text> - Määrittää kaikkien
+          kartalle piirrettävien viivojen leveyden.  Asetus muuttaa merkkien,
+          reittisuunnitelmien ja -jälkien, sekä POI-pisteiden kuvien koon.
+        </listitem>
+        <listitem>
+          <display_text>Pidä näyttö päällä vain koko näytön ollessa
+          käytössä</display_text> - Määrittelee miten Maemo Mapper
+          rajoittaa näytön taustavalon päällä oloa koko näytön ollessa
+          valittuna.  Jos valintaruutu ei ole määriteltynä, Maemo Mapper pitää
+          taustavalon päällä aina liikkuessasi.  Jos valintaruutu on valittuna,
+          näyttö on päällä ainoastaan koko näytön ollessa Maemo Mapperin
+          käytössä.
+        </listitem>
+        <listitem>
+          <display_text>Tietojen kirjasinkoko</display_text> - Määrittää
+          minkä kokoisella kirjasimella tiedot näytetään käyttäjälle
+          näytön oikeassa yläkulmassa.  Asetus vaikuttaa myös reittisuunnitelman
+          opasteiden näyttämiseen.
+        </listitem>
+        <listitem>
+          <display_text>Yksiköt</display_text> - Määrittää mitä yksiköitä
+          käytetään matkan ja nopeuden ilmaisemiseen näytöllä.
+        </listitem>
+        <listitem>
+          <display_text>Asteiden muoto</display_text> - Määrittää kuinka
+          latitudi ja longitudi näytetään näytöllä.
+        </listitem>
+        <listitem>
+          <display_text>Nopeusrajoitus</display_text> - Antaa ilmoituksen, 
+          kun ylität valintaruudussa annetun nopeusrajoituksen arvon. 
+          Käytetty nopeuden yksikkö valitaan
+          <display_text>Yksiköt</display_text> valintalistasta.
+        </listitem>
+        <listitem>
+          <display_text>Sijainti</display_text> - Määrittää missä osassa
+          näyttöä nopeusrajoituksen varoitus on nähtävissä.
+        </listitem>
+      </list>
+      <heading>POI</heading>
+      <para>
+        <display_text>POI</display_text>-välilehti antaa mahdollisuuden
+        määritellä POI-tietokannan sijainnin ja sen, kuinka POI-pisteet
+        näytetään näytöllä.
+      </para>
+      <list>
+        <listitem>
+          <display_text>POI-tietokanta</display_text> - Tietokannan sijainti
+          laitteen tiedostojärjestelmässä.  Tietokannan täytyy olla sqlite3
+          muotoinen.  Kun Maemo Mapper on käynnistetty ensimmäisen kerran,
+          luodaan automaattisesti tyhjä POI-tietokanta.
+        </listitem>
+        <listitem>
+          <display_text>Näytä POI:t alle zoom tason</display_text> - Määrittää
+          maksimi zoom tason (kauimpana maan pinnalta), millä POI:t näytetään
+          näytöllä.  Kun zoom taso on tämän arvon yläpuolella, POI-pisteitä ei
+          näytetä.
+        </listitem>
+      </list>
+    </topic>
+    <topic>
+      <topictitle>Tietoja ohjelmasta Maemo Mapper</topictitle>
+      <context contextUID="help_maemomapper_about"/>
+      <para>
+        Asennettu versio: __VERSION__
+      </para>
+      <para>
+        Maemo Mapperin on suunnitellut ja luonut John Costigan (aka
+       <display_text>gnuite</display_text>).
+      </para>
+      <para>
+        Copyright © 2006-2007 John Costigan.
+      </para>
+      <para>
+        POI ja GPS-Info koodin on alunperin luonut Cezary Jackiewicz.
+      </para>
+      <para>
+       Karttojen oletuslähde on http://www.openstreetmap.org/ - ja muut
+        karttavarastot ovat kyseisten karttojen tarjoajien lisenssiehtojen
+        alaisia, eivätkä ne välttämättä sovellu Maemo Mapperin kanssa käytettäviksi.
+        Joissakin tilanteissa tällaisten karttavarastojen käyttö saattaa olla
+        karttojen tarjoajan lisenssiehtojen vastaista.  Maemo Mapperilla
+        erikseen ladatut karttavarastot saattavat sisältää myös tällaisia
+        rajoitteita.  Mikäli et ole varma onko jonkin karttavaraston käyttö
+        karttojen tarjoajan lisenssiehtojen mukaista, niin sinun tulisi poistaa
+        se käytössä olevien karttavarastojen listalta.  Karttavarastojen käyttö
+        on jokaisen omalla vastuulla.
+      </para>
+      <para>
+        Tämä on vapaa ohjelma: tätä ohjelmaa saa levittää edelleen ja muuttaa
+        Free Software Foundationin julkaiseman GNU General Public Licensen
+        (GPL-lisenssi) version 2 tai (valinnan mukaan) myöhemmän version ehtojen
+        mukaisesti.
+      </para>
+      <para>
+        Tätä ohjelmaa levitetään siinä toivossa, että se olisi hyödyllinen mutta
+        ilman mitään takuuta; edes hiljaista takuuta kaupallisesti
+        hyväksyttävästä laadusta tai soveltuvuudesta tiettyyn tarkoitukseen.
+        Katso GPL- lisenssistä lisää yksityiskohtia.
+      </para>
+      <para>
+        Tämän ohjelman mukana pitäisi tulla kopio GPL-lisenssistä. Jos näin ei
+        ole, katso http://www.gnu.org/licenses/. 
+      </para>
+    </topic>
+  </folder>
+</ossohelpsource>
index 0dd650c353ac0f2c9a53ed59f2c014df79f9719a..327b6497e5bcd3e7e5d5a8be0946b067405f9039 100644 (file)
@@ -1,3 +1,29 @@
+maemo-mapper (2.0) unstable; urgency=low
+
+  * Changed map repositories to use gdbm instead of file system.
+  * Changed track and route temporary files to use sqlite instead of GPX.
+    (Save and Open operations still use GPX.)
+  * Changed map retrieval to use threads.
+  * Changed NMEA retrieval to support GPSD and to use a separate thread.
+  * Added POI import, download, browser, and export.
+  * Added support for view rotation.  Also threaded view creation.
+  * Added an on-screen compass that points north.
+  * Added support for dragging the view in order to pan.
+  * Added support for repositories with no map cache at all.
+  * Added hourglass to notify users when a redraw is occurring.
+  * Replaced old internet connectivity with  support for libconic0.
+  * Reorganized the view-related menu items into an expanded "View" menu.
+  * Added Pre-cache option to reduce the amount of time that black areas are
+    on the screen while in Auto-download mode.
+  * Modified the Waypoint Notification Window to use a progress bar; this
+    should also fix some of the flicker that used to occur.
+  * Improved the robustness of bluetooth receiver error handling (no more
+      crashing when out of range).
+  * Improved memory utilization.
+  * Reorganized the code for greater readability.
+
+ -- John Costigan <gnuite@gmail.com>  Mon, 1 Oct 2007 22:08:00 -0400
+
 maemo-mapper (1.4.7) unstable; urgency=low
 
   * Added "Avoid Highways" option to the "Download Route" dialog.
@@ -5,7 +31,7 @@ maemo-mapper (1.4.7) unstable; urgency=low
   * Fixed bug with sensitivity of the "Auto-Update" checkbox.
   * Fixed bug that caused Auto-Update to be constantly invoked.
 
- -- John Costigan <gnuite@gmail.com>  Say, 7 Jul 2007 21:52:00 -0400
+ -- John Costigan <gnuite@gmail.com>  Sat, 7 Jul 2007 21:52:00 -0400
 
 maemo-mapper (1.4.6) unstable; urgency=low
 
index ff96d144611fb5b281680c240b1ab66a10de62ed..75175c37a54a073219ed1ad396e9b1f7938743c2 100755 (executable)
@@ -26,6 +26,8 @@ endif
 
 ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS)))
        CFLAGS += -g -O0 -DDEBUG
+else
+       CFLAGS += -DNDEBUG
 endif
 
 configure: configure-stamp
diff --git a/dpkg-build.sh b/dpkg-build.sh
deleted file mode 100755 (executable)
index e4d5a85..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/sh
-#
-# This little script builds an appropriately-versioned .deb file depending
-# on your exact architecture (as defined in CFLAGS).
-# On an N800 (-mcpu=arm1136jf-s), the version is suffixed with "-3".
-# On a 770 (-mcpu=arm926ej-s), the version is suffixed with "-2".
-# In all other cases, the version is suffixed with "-1".
-# 
-
-CHANGELOG=`dirname $0`/debian/changelog
-
-case $CFLAGS in
-    *-mcpu=arm1136jf-s*)
-    VERSION_SUFFIX=-3
-    DBP_EXTRA=-B
-    ;;
-    *-mcpu=arm926ej-s*)
-    VERSION_SUFFIX=-2
-    DBP_EXTRA=-B
-    ;;
-    *)
-    VERSION_SUFFIX=-1
-    DBP_EXTRA=
-esac
-
-head -n 1 $CHANGELOG | sed "s/)/$VERSION_SUFFIX)/" > $CHANGELOG.new
-awk 'NR>1 {print}' $CHANGELOG >> $CHANGELOG.new
-mv $CHANGELOG $CHANGELOG.old
-mv $CHANGELOG.new $CHANGELOG
-
-dpkg-buildpackage -rfakeroot -I.svn $DBP_EXTRA
-
-mv $CHANGELOG.old $CHANGELOG
index cfd6e18f6dd59c87be19ed193bf196028fa1caa7..70c65fba9036b410e1b610874dde716e67de2659 100644 (file)
@@ -1,3 +1,17 @@
 # List of MaemoPad source files to be localized
 
-src/maemo-mapper.c
+src/cmenu.c
+src/data.c
+src/display.c
+src/gdk-pixbuf-rotate.c
+src/gps.c
+src/gpx.c
+src/input.c
+src/main.c
+src/maps.c
+src/marshal.c
+src/menu.c
+src/path.c
+src/poi.c
+src/settings.c
+src/util.c
index d1023c533468546569821c24b2338361a2801be2..a9a54a12f5dd0a8b87807a6c0af5a28329051d17 100644 (file)
@@ -11,7 +11,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: maemo-mapper 1.2.4\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-07-07 20:45-0400\n"
+"POT-Creation-Date: 2007-11-01 15:35-0400\n"
 "PO-Revision-Date: 2006-10-28 22:19-0400\n"
 "Last-Translator: David Davidov <dave@del.bg>\n"
 "Language-Team: John Costigan <gnuite@gmail.com>\n"
@@ -19,83 +19,84 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: ../src/maemo-mapper.c:12960
+#: ../src/poi.c:922
 msgid "# POIs"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6293
+#: ../src/menu.c:1597
 #, fuzzy
 msgid "About..."
 msgstr "относно"
 
-#: ../src/maemo-mapper.c:12916
-msgid "Add"
-msgstr "Добави"
-
-#: ../src/maemo-mapper.c:12650
+#: ../src/poi.c:604
 msgid "Add Category"
 msgstr "Добави категория"
 
-#: ../src/maemo-mapper.c:13149
+#: ../src/poi.c:1123
 msgid "Add POI"
 msgstr "Добави POI"
 
-#: ../src/maemo-mapper.c:6427 ../src/maemo-mapper.c:6456
+#: ../src/cmenu.c:610 ../src/cmenu.c:639
 #, fuzzy
 msgid "Add POI..."
 msgstr "Добави POI..."
 
-#: ../src/maemo-mapper.c:6423 ../src/maemo-mapper.c:6478
+#: ../src/cmenu.c:606 ../src/cmenu.c:661
 msgid "Add Route Point"
 msgstr "Добави Route Point"
 
-#: ../src/maemo-mapper.c:13601
+#: ../src/path.c:1334
 #, fuzzy
 msgid "Add Waypoint"
 msgstr "Добави Точки по пътя"
 
-#: ../src/maemo-mapper.c:6425 ../src/maemo-mapper.c:6480
+#: ../src/cmenu.c:608 ../src/cmenu.c:663
 #, fuzzy
 msgid "Add Waypoint..."
 msgstr "Добави Точки по пътя..."
 
-#: ../src/maemo-mapper.c:10910
+#: ../src/poi.c:878
+#, fuzzy
+msgid "Add..."
+msgstr "Добави POI..."
+
+#: ../src/menu.c:837
 #, fuzzy
 msgid "Address"
 msgstr "Добави"
 
-#: ../src/maemo-mapper.c:10987
+#: ../src/menu.c:862
 msgid "Address Located"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6256
+#: ../src/menu.c:1489
 #, fuzzy
 msgid "Address..."
 msgstr "Добави POI..."
 
-#: ../src/maemo-mapper.c:5029
+#: ../src/settings.c:1126
 msgid "Advance Notice"
 msgstr "Придвижване инфо"
 
-#: ../src/maemo-mapper.c:12100
+#: ../src/maps.c:2101
 msgid "Along Route - Radius (tiles):"
 msgstr "Около маршрут - Радиус (блокчета):"
 
-#: ../src/maemo-mapper.c:2813
+#: ../src/display.c:805
 msgid "Altitude"
 msgstr "Височина"
 
-#: ../src/maemo-mapper.c:4501
+#: ../src/settings.c:548
 msgid "An error occurred while attempting to scan for bluetooth devices."
 msgstr ""
 
-#: ../src/maemo-mapper.c:11489
+#: ../src/maps.c:1517
 msgid ""
 "An error occurred while retrieving the repositories.  The web service may be "
 "temporarily down."
 msgstr ""
 
-#: ../src/maemo-mapper.c:8829
+#: ../src/gps.c:955
 msgid ""
 "An error occurred while trying to reset the bluetooth radio.\n"
 "\n"
@@ -107,618 +108,795 @@ msgstr ""
 "Променихте ли файла\n"
 "/etc/sudoers?"
 
-#: ../src/maemo-mapper.c:5025
+#: ../src/settings.c:1122
 msgid "Announce"
 msgstr "Анонси"
 
-#: ../src/maemo-mapper.c:12137
+#: ../src/maps.c:2138
 msgid "Area"
 msgstr "Зона"
 
-#: ../src/maemo-mapper.c:4994 ../src/maemo-mapper.c:6227
+#: ../src/menu.c:1540 ../src/settings.c:1061
 msgid "Auto-Center"
 msgstr "Авто-Центр."
 
-#: ../src/maemo-mapper.c:10774
+#: ../src/menu.c:1114
 msgid "Auto-Center Mode: Lat/Lon"
 msgstr "Авто-Центриране: Дълж/Шир"
 
-#: ../src/maemo-mapper.c:10759
+#: ../src/menu.c:1097
 msgid "Auto-Center Mode: Lead"
 msgstr "Авто-Центриране: Изпреварващо"
 
-#: ../src/maemo-mapper.c:10788
+#: ../src/menu.c:1130
 msgid "Auto-Center Off"
 msgstr "Авто-Центриране Изкл."
 
-#: ../src/maemo-mapper.c:6172
+#: ../src/menu.c:1419
 msgid "Auto-Download"
 msgstr "Авто-Изтегляне"
 
-#: ../src/maemo-mapper.c:10064
+#: ../src/settings.c:1221
+#, fuzzy
+msgid "Auto-Download Pre-cache"
+msgstr "Авто-Изтегляне"
+
+#: ../src/menu.c:1454
+#, fuzzy
+msgid "Auto-Rotate"
+msgstr "Авто-Обновяване"
+
+#: ../src/menu.c:624
+msgid "Auto-Rotate Disabled"
+msgstr ""
+
+#: ../src/menu.c:619
+msgid "Auto-Rotate Enabled"
+msgstr ""
+
+#: ../src/path.c:1113
 msgid "Auto-Update"
 msgstr "Авто-Обновяване"
 
-#: ../src/maemo-mapper.c:10076
+#: ../src/path.c:1119
 msgid "Avoid Highways"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8098
+#: ../src/poi.c:1749
+#, fuzzy
+msgid "Bear."
+msgstr "Изчистване"
+
+#: ../src/main.c:310
+#, fuzzy
+msgid "Bluetooth"
+msgstr "Рестарт Bluetooth"
+
+#: ../src/main.c:307
 #, fuzzy
 msgid "Bottom-Left"
 msgstr "Долу/Дясно"
 
-#: ../src/maemo-mapper.c:8097 ../src/maemo-mapper.c:12208
+#: ../src/main.c:306 ../src/maps.c:2209
 msgid "Bottom-Right"
 msgstr "Долу/Дясно"
 
-#: ../src/maemo-mapper.c:3767
+#: ../src/path.c:967
 msgid "Break already inserted."
 msgstr ""
 
-#: ../src/maemo-mapper.c:5191 ../src/maemo-mapper.c:11297
+#: ../src/poi.c:2509
+#, fuzzy
+msgid "Browse POIs"
+msgstr "Вкл/изкл GPS"
+
+#: ../src/maps.c:1323 ../src/menu.c:1403 ../src/settings.c:1054
+#: ../src/settings.c:1278
 msgid "Browse..."
 msgstr "Избор..."
 
-#: ../src/maemo-mapper.c:2996
+#: ../src/poi.c:153
 msgid "Bus stops, airports, train stations, etc."
 msgstr ""
 
-#: ../src/maemo-mapper.c:3001
+#: ../src/poi.c:158
 msgid "Business"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12091
+#: ../src/maps.c:2092
 msgid "By Area (see tab)"
 msgstr "Зона (виж таб)"
 
-#: ../src/maemo-mapper.c:11287
-msgid "Cache Dir."
+#: ../src/maps.c:1313
+#, fuzzy
+msgid "Cache DB"
 msgstr "Кеш Директория"
 
-#: ../src/maemo-mapper.c:11227
+#: ../src/maps.c:1253
 msgid ""
 "Cannot delete the last repository - there must be at lease one repository."
 msgstr "Не мога да изтрия последното хранилище - трябва да остане поне едно."
 
-#: ../src/maemo-mapper.c:12416
+#: ../src/menu.c:1177
+#, fuzzy
 msgid ""
-"Cannot enable GPS until a GPS Receiver MAC is set in the Settings dialog box."
+"Cannot enable GPS until a GPS receiver is set up in the Settings dialog box."
 msgstr ""
 "Не мога да разреша GPS докато не е посочен MAC адреса на приемника в "
 "Настрийки."
 
-#: ../src/maemo-mapper.c:8597 ../src/maemo-mapper.c:13185
+#: ../src/menu.c:1405
+#, fuzzy
+msgid "Categories..."
+msgstr "POI Категории..."
+
+#: ../src/poi.c:458 ../src/poi.c:1159 ../src/poi.c:1512 ../src/poi.c:1732
+#: ../src/poi.c:2089 ../src/poi.c:2243 ../src/poi.c:2540
 msgid "Category"
 msgstr "Категория"
 
-#: ../src/maemo-mapper.c:6139 ../src/maemo-mapper.c:6159
-#: ../src/maemo-mapper.c:12044
+#: ../src/poi.c:1928 ../src/poi.c:2003
+msgid "Checked POI Actions..."
+msgstr ""
+
+#: ../src/maps.c:2045 ../src/menu.c:1371 ../src/menu.c:1391
 msgid "Clear"
 msgstr "Изчистване"
 
-#: ../src/maemo-mapper.c:8060
+#: ../src/main.c:269
 #, fuzzy
 msgid "Clear Track"
 msgstr "Вкл/изкл Път"
 
-#: ../src/maemo-mapper.c:6295
+#: ../src/menu.c:1448
+#, fuzzy
+msgid "Clockwise"
+msgstr "Затваряне"
+
+#: ../src/menu.c:1599
 msgid "Close"
 msgstr "Затваряне"
 
-#: ../src/maemo-mapper.c:4729
+#: ../src/settings.c:760
 msgid "Colors"
 msgstr "Цветове"
 
-#: ../src/maemo-mapper.c:4953
+#: ../src/settings.c:993
 msgid "Colors..."
 msgstr "Цветове..."
 
-#: ../src/maemo-mapper.c:11803 ../src/maemo-mapper.c:11890
+#: ../src/menu.c:1515
+msgid "Compass Rose"
+msgstr ""
+
+#: ../src/maps.c:1784 ../src/maps.c:1880
 msgid "Confirm DELETION of"
 msgstr "Потвърдете ИЗТРИВАНЕ на"
 
-#: ../src/maemo-mapper.c:11234
+#: ../src/maps.c:1260
 msgid "Confirm delete of repository"
 msgstr "Потвърдете изтриване хранилище"
 
-#: ../src/maemo-mapper.c:13966
+#: ../src/cmenu.c:385
 msgid "Confirm delete of waypoint"
 msgstr "Потвърдете изтриване на точка по пътя"
 
-#: ../src/maemo-mapper.c:11809 ../src/maemo-mapper.c:11896
+#: ../src/maps.c:1790 ../src/maps.c:1886
 msgid "Confirm download of"
 msgstr "Потвърдете изтегляне на"
 
-#: ../src/maemo-mapper.c:4663
+#: ../src/settings.c:699
 msgid "Continue?"
 msgstr ""
 
-#: ../src/maemo-mapper.c:13451
+#: ../src/display.c:2453
 msgid "Copy"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6446
+#: ../src/cmenu.c:629
 #, fuzzy
 msgid "Copy Description"
 msgstr "Описание"
 
-#: ../src/maemo-mapper.c:6444
+#: ../src/cmenu.c:627
 #, fuzzy
 msgid "Copy Lat/Lon"
 msgstr "Покажи Шир/Дълж"
 
-#: ../src/maemo-mapper.c:13684
+#: ../src/menu.c:1450
+#, fuzzy
+msgid "Counter"
+msgstr "Маршрут"
+
+#: ../src/path.c:1417
 msgid ""
 "Creating a \"waypoint\" with no description actually adds a break point.  Is "
 "that what you want?"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2286
+#: ../src/display.c:278
 msgid "DGPS"
 msgstr ""
 
-#: ../src/maemo-mapper.c:5129
+#: ../src/poi.c:2079
+#, fuzzy
+msgid "Default Category"
+msgstr "Изтриване категория?"
+
+#: ../src/settings.c:1208
 msgid "Degrees Format"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12631 ../src/maemo-mapper.c:13124
-msgid "Delete"
-msgstr "Изтриване"
-
-#: ../src/maemo-mapper.c:12081
+#: ../src/maps.c:2082
 msgid "Delete Maps"
 msgstr "Изтриване Карти"
 
-#: ../src/maemo-mapper.c:13008
+#: ../src/poi.c:958
 msgid "Delete POI?"
 msgstr "Изтриване POI?"
 
-#: ../src/maemo-mapper.c:12552
+#: ../src/poi.c:506
 msgid "Delete category?"
 msgstr "Изтриване категория?"
 
-#: ../src/maemo-mapper.c:6453 ../src/maemo-mapper.c:11586
+#: ../src/poi.c:1843
+#, fuzzy
+msgid "Delete selected POI?"
+msgstr "Изтриване POI?"
+
+#: ../src/cmenu.c:636 ../src/maps.c:1614 ../src/poi.c:585 ../src/poi.c:1096
+#: ../src/poi.c:1943
 msgid "Delete..."
 msgstr "Изтриване..."
 
-#: ../src/maemo-mapper.c:4489 ../src/maemo-mapper.c:10513
-#: ../src/maemo-mapper.c:12669 ../src/maemo-mapper.c:12955
-#: ../src/maemo-mapper.c:13212 ../src/maemo-mapper.c:13626
+#: ../src/menu.c:310 ../src/path.c:1359 ../src/poi.c:623 ../src/poi.c:917
+#: ../src/poi.c:1174 ../src/settings.c:536
 msgid "Description"
 msgstr "Описание"
 
-#: ../src/maemo-mapper.c:10093
+#: ../src/path.c:1136
 msgid "Destination"
 msgstr "Край"
 
-#: ../src/maemo-mapper.c:6278
+#: ../src/menu.c:1582
 msgid "Details..."
 msgstr "Подробности..."
 
-#: ../src/maemo-mapper.c:2989
-msgid "Dining"
-msgstr ""
+#: ../src/gps.c:779
+#, fuzzy
+msgid "Disconnecting from GPS receiver"
+msgstr "Търси GPS приемник"
+
+#: ../src/poi.c:1740
+#, fuzzy
+msgid "Dist."
+msgstr "Покажи разстояние до"
 
-#: ../src/maemo-mapper.c:3365 ../src/maemo-mapper.c:3425
-#: ../src/maemo-mapper.c:13566
+#: ../src/cmenu.c:136 ../src/path.c:517 ../src/path.c:577
 #, fuzzy
 msgid "Distance"
 msgstr "Покажи разстояние до"
 
-#: ../src/maemo-mapper.c:11354
+#: ../src/maps.c:1382
 msgid "Double Pixels"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12068
+#: ../src/main.c:195 ../src/menu.c:1466
+msgid "Down"
+msgstr ""
+
+#: ../src/maps.c:2069
 msgid "Download Maps"
 msgstr "Изтегляне Карти"
 
-#: ../src/maemo-mapper.c:10034
+#: ../src/poi.c:2202
+#, fuzzy
+msgid "Download POIs"
+msgstr "Изтегляне Карти"
+
+#: ../src/path.c:1071
 msgid "Download Route"
 msgstr "Изтегляне Маршрут"
 
-#: ../src/maemo-mapper.c:6420 ../src/maemo-mapper.c:6451
-#: ../src/maemo-mapper.c:6475
+#: ../src/cmenu.c:603 ../src/cmenu.c:634 ../src/cmenu.c:658
 msgid "Download Route to..."
 msgstr "Изтегляне на маршрут в..."
 
-#: ../src/maemo-mapper.c:11317
+#: ../src/maps.c:1345
 msgid "Download Zoom Steps"
 msgstr "Изтегляне Мащаб Стъпки"
 
-#: ../src/maemo-mapper.c:6129 ../src/maemo-mapper.c:11567
+#: ../src/maps.c:1595 ../src/menu.c:1361 ../src/menu.c:1401
 msgid "Download..."
 msgstr "Изтегляне..."
 
-#: ../src/maemo-mapper.c:6937
-msgid "Downloading maps"
-msgstr "Изтегляне карти"
+#: ../src/maps.c:654 ../src/maps.c:667
+msgid "Downloaded maps will not be cached."
+msgstr ""
 
-#: ../src/maemo-mapper.c:12913
-msgid "Edit"
-msgstr "Редакт."
+#: ../src/menu.c:1479
+msgid "East"
+msgstr ""
 
-#: ../src/maemo-mapper.c:13208
+#: ../src/poi.c:1170
 msgid "Edit Categories..."
 msgstr "Редакт. категории..."
 
-#: ../src/maemo-mapper.c:12625
+#: ../src/poi.c:579
 msgid "Edit Category"
 msgstr "Редакт. категория"
 
-#: ../src/maemo-mapper.c:13118
+#: ../src/poi.c:1090
 msgid "Edit POI"
 msgstr "Редакт. POI"
 
-#: ../src/maemo-mapper.c:3000
+#: ../src/poi.c:875 ../src/poi.c:1999
+#, fuzzy
+msgid "Edit..."
+msgstr "Редакт."
+
+#: ../src/poi.c:157
 msgid "Elementary schools, college campuses, etc."
 msgstr ""
 
-#: ../src/maemo-mapper.c:6270
+#: ../src/menu.c:1574
 msgid "Enable GPS"
 msgstr "Използвай GPS"
 
-#: ../src/maemo-mapper.c:5042
+#: ../src/settings.c:1139
 msgid "Enable Voice Synthesis (requires flite)"
 msgstr "Разреши гласов синтез (изисква flite)"
 
-#: ../src/maemo-mapper.c:12693 ../src/maemo-mapper.c:12945
+#: ../src/poi.c:647 ../src/poi.c:907
 msgid "Enabled"
 msgstr "Разреши"
 
-#: ../src/maemo-mapper.c:7185
-msgid ""
-"Error in download.  Check internet connection and/or Map Repository URL "
-"Format."
+#: ../src/poi.c:1305
+#, fuzzy
+msgid "Error adding POI"
+msgstr "Проблем при добавяне на POI"
+
+#: ../src/poi.c:710
+#, fuzzy
+msgid "Error adding category"
+msgstr "Проблем при добавяне категория"
+
+#: ../src/gps.c:631
+#, fuzzy
+msgid "Error connecting to GPS receiver."
+msgstr "Търси GPS приемник"
+
+#: ../src/gps.c:617
+msgid "Error connecting to GPSD."
 msgstr ""
 
-#: ../src/maemo-mapper.c:8371 ../src/maemo-mapper.c:10319
-#: ../src/maemo-mapper.c:10363 ../src/maemo-mapper.c:10437
+#: ../src/poi.c:521 ../src/poi.c:969 ../src/poi.c:1871
+#, fuzzy
+msgid "Error deleting POI"
+msgstr "Проблем при изтриване на POI"
+
+#: ../src/poi.c:530
+#, fuzzy
+msgid "Error deleting category"
+msgstr "Проблем при изтриване категория"
+
+#: ../src/main.c:488 ../src/menu.c:122 ../src/menu.c:234 ../src/path.c:678
+#: ../src/poi.c:2130 ../src/poi.c:2481
 msgid "Error parsing GPX file."
 msgstr "Грешка при разчитане (parsing) GPX файл."
 
-#: ../src/maemo-mapper.c:1501
+#: ../src/gps.c:667
+#, fuzzy
+msgid "Error reading GPS data."
+msgstr "Грешка при разчитане (parsing) GPX файл."
+
+#: ../src/poi.c:754
+#, fuzzy
+msgid "Error updating Category"
+msgstr "Проблем при обновяване на Категория"
+
+#: ../src/poi.c:1285 ../src/poi.c:1583
+#, fuzzy
+msgid "Error updating POI"
+msgstr "Проблем при обновяване на POI"
+
+#: ../src/poi.c:695
+#, fuzzy
+msgid "Error updating category"
+msgstr "Проблем при обновяване на категория"
+
+#: ../src/gpx.c:478 ../src/gpx.c:805
 msgid "Error while writing to file"
 msgstr "Грешка при запис във файл"
 
-#: ../src/maemo-mapper.c:10459 ../src/maemo-mapper.c:10618
+#: ../src/poi.c:103
+#, fuzzy
+msgid "Error with POI database"
+msgstr "Проблем с POI база данни"
+
+#: ../src/menu.c:153 ../src/menu.c:256 ../src/poi.c:1911
 msgid "Error writing GPX file."
 msgstr "Грешка при запис на GPX файл."
 
-#: ../src/maemo-mapper.c:3148
+#: ../src/gps.c:801
 msgid "Establishing GPS fix"
 msgstr "Установяване GPS фикс"
 
-#: ../src/maemo-mapper.c:2290
+#: ../src/display.c:282
 msgid "Estimated"
 msgstr ""
 
-#: ../src/maemo-mapper.c:3903
-msgid "Failed to connect to GPS receiver.  Retry?"
+#: ../src/poi.c:1948
+msgid "Export to GPX..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:10251 ../src/maemo-mapper.c:10957
+#: ../src/gps.c:923
+#, fuzzy
+msgid "Failed to connect to Bluetooth GPS receiver."
+msgstr "Неуспешно свързване с  GPX сървър за инструкции"
+
+#: ../src/util.c:139
 msgid "Failed to connect to GPX Directions server"
 msgstr "Неуспешно свързване с  GPX сървър за инструкции"
 
-#: ../src/maemo-mapper.c:5577
+#: ../src/settings.c:1646
 msgid "Failed to initialize GConf.  Quitting."
 msgstr "Неуспешна инициализация на GConf.  Прекъсвам."
 
-#: ../src/maemo-mapper.c:4047
+#: ../src/settings.c:72
 msgid "Failed to initialize GConf.  Settings were not saved."
 msgstr "Неуспешна инициализация на GConf.  Запазих настройките."
 
-#: ../src/maemo-mapper.c:7750 ../src/maemo-mapper.c:8360
+#: ../src/display.c:2561 ../src/main.c:476
 msgid "Failed to open file for reading"
 msgstr "Неуспех при отваряне за четене"
 
-#: ../src/maemo-mapper.c:7403 ../src/maemo-mapper.c:7751
+#: ../src/display.c:2562
 msgid "Failed to open file for writing"
 msgstr "Неуспех при отваряне за запис"
 
-#: ../src/maemo-mapper.c:3014
+#: ../src/maps.c:652 ../src/maps.c:666
+#, fuzzy
+msgid "Failed to open map database for repository"
+msgstr "Неуспешно отваряне/създаване на база данни"
+
+#: ../src/poi.c:171
 msgid "Failed to open or create database"
 msgstr "Неуспешно отваряне/създаване на база данни"
 
-#: ../src/maemo-mapper.c:1502
+#: ../src/path.c:1553
+msgid "Failed to open path database. Tracks and routes will not be saved."
+msgstr ""
+
+#: ../src/path.c:195 ../src/path.c:221 ../src/path.c:240
+msgid "Failed to write to path database. Tracks and routes may not be saved."
+msgstr ""
+
+#: ../src/main.c:312
+msgid "File"
+msgstr ""
+
+#: ../src/settings.c:1044
+msgid "File Path"
+msgstr ""
+
+#: ../src/gpx.c:479 ../src/gpx.c:806
 msgid "File is incomplete."
 msgstr "Незавършен файл."
 
-#: ../src/maemo-mapper.c:2858
+#: ../src/display.c:850
 msgid "Fix"
 msgstr "Фикс"
 
-#: ../src/maemo-mapper.c:2867
+#: ../src/display.c:859
 msgid "Fix Quality"
 msgstr "Фикс качество"
 
-#: ../src/maemo-mapper.c:2289
+#: ../src/settings.c:1093
+#, fuzzy
+msgid "Fixed"
+msgstr "Фикс"
+
+#: ../src/display.c:281
 msgid "Float RTK"
 msgstr ""
 
-#: ../src/maemo-mapper.c:13442
+#: ../src/display.c:2444
 #, fuzzy
 msgid "Format"
 msgstr "URI формат"
 
-#: ../src/maemo-mapper.c:2985
-msgid "Fuel"
-msgstr ""
-
-#: ../src/maemo-mapper.c:6189
+#: ../src/menu.c:1564
 msgid "Full Screen"
 msgstr "Пълноекранно"
 
-#: ../src/maemo-mapper.c:4747 ../src/maemo-mapper.c:4964
-#: ../src/maemo-mapper.c:6266
+#: ../src/menu.c:1570 ../src/settings.c:778 ../src/settings.c:1004
 msgid "GPS"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2761
+#: ../src/display.c:753
 msgid "GPS Details"
 msgstr "GPS подробности"
 
-#: ../src/maemo-mapper.c:2774
+#: ../src/display.c:766
 msgid "GPS Information"
 msgstr "GPS Информация"
 
-#: ../src/maemo-mapper.c:6258 ../src/maemo-mapper.c:12151
+#: ../src/maps.c:2152 ../src/menu.c:1491
 msgid "GPS Location"
 msgstr "GPS позиция"
 
-#: ../src/maemo-mapper.c:3004
+#: ../src/main.c:311
+msgid "GPSD"
+msgstr ""
+
+#: ../src/settings.c:1025
+msgid "GPSD Host"
+msgstr ""
+
+#: ../src/poi.c:161
 msgid "General landmarks."
 msgstr ""
 
-#: ../src/maemo-mapper.c:3002
+#: ../src/poi.c:159
 msgid "General places of business."
 msgstr ""
 
-#: ../src/maemo-mapper.c:6250
+#: ../src/menu.c:1483 ../src/poi.c:1996
 msgid "Go to"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10900
+#: ../src/menu.c:827
 msgid "Go to Address"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10806
+#: ../src/menu.c:731
 #, fuzzy
 msgid "Go to Lat/Lon"
 msgstr "Покажи Шир/Дълж"
 
-#: ../src/maemo-mapper.c:6483
+#: ../src/cmenu.c:666
 msgid "Go to Nearest"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6460
+#: ../src/cmenu.c:643
 msgid "Go to Next"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4608
+#: ../src/settings.c:644
 msgid "Hardware Keys"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4950
+#: ../src/settings.c:990
 msgid "Hardware Keys..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:2822
+#: ../src/display.c:814
 msgid "Heading"
 msgstr "Посока"
 
-#: ../src/maemo-mapper.c:6291
+#: ../src/menu.c:1595
 #, fuzzy
 msgid "Help..."
 msgstr "Помощ"
 
-#: ../src/maemo-mapper.c:2988
+#: ../src/poi.c:145
 msgid "Houses, apartments, or other residences of import."
 msgstr ""
 
-#: ../src/maemo-mapper.c:12937
+#: ../src/poi.c:899
 msgid "ID"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2994
+#: ../src/menu.c:1399
+msgid "Import..."
+msgstr ""
+
+#: ../src/poi.c:151
 msgid "Indoor or Outdoor places to have fun."
 msgstr ""
 
-#: ../src/maemo-mapper.c:5102
+#: ../src/settings.c:1174
 #, fuzzy
-msgid "Information Font Size"
+msgid "Info Font Size"
 msgstr "GPS Информация"
 
-#: ../src/maemo-mapper.c:6151
+#: ../src/menu.c:1383
 #, fuzzy
 msgid "Insert Break"
 msgstr "Вмъкване прекъсване"
 
-#: ../src/maemo-mapper.c:10493
+#: ../src/menu.c:290
 #, fuzzy
 msgid "Insert Mark"
 msgstr "Вмъкване прекъсване"
 
-#: ../src/maemo-mapper.c:6153
+#: ../src/menu.c:1385
 #, fuzzy
 msgid "Insert Mark..."
 msgstr "Вмъкване прекъсване"
 
-#: ../src/maemo-mapper.c:8059
+#: ../src/main.c:268
 #, fuzzy
 msgid "Insert Track Break"
 msgstr "Вмъкване прекъсване"
 
-#: ../src/maemo-mapper.c:12324
+#: ../src/maps.c:2342
 msgid "Invalid Bottom-Right Latitude"
 msgstr "Невалидна ширина долу/дясно"
 
-#: ../src/maemo-mapper.c:12331
+#: ../src/maps.c:2349
 msgid "Invalid Bottom-Right Longitude"
 msgstr "Невалидна дължина долу/дясно"
 
-#: ../src/maemo-mapper.c:10865 ../src/maemo-mapper.c:13267
+#: ../src/menu.c:792 ../src/poi.c:1224
 #, fuzzy
 msgid "Invalid Latitude"
 msgstr "Невалидна ширина"
 
-#: ../src/maemo-mapper.c:10872 ../src/maemo-mapper.c:13274
+#: ../src/menu.c:799 ../src/poi.c:1231
 #, fuzzy
 msgid "Invalid Longitude"
 msgstr "Невалидна дължина"
 
-#: ../src/maemo-mapper.c:9534 ../src/maemo-mapper.c:9545
+#: ../src/gps.c:66 ../src/gps.c:77
 msgid "Invalid NMEA input from receiver!"
 msgstr "Невалидни NMEA данни от приемника!"
 
-#: ../src/maemo-mapper.c:12310
+#: ../src/maps.c:2328
 msgid "Invalid Top-Left Latitude"
 msgstr "Невалидна ширина горе/ляво"
 
-#: ../src/maemo-mapper.c:12317
+#: ../src/maps.c:2335
 msgid "Invalid Top-Left Longitude"
 msgstr "Невалидна дължина горе/ляво"
 
-#: ../src/maemo-mapper.c:10971
+#: ../src/util.c:150
 #, fuzzy
 msgid "Invalid address."
 msgstr "Невалидна ширина"
 
-#: ../src/maemo-mapper.c:10264
+#: ../src/poi.c:2460
+#, fuzzy
+msgid "Invalid origin or query."
+msgstr "Невалидна дължина"
+
+#: ../src/path.c:657
 msgid "Invalid source or destination."
 msgstr ""
 
-#: ../src/maemo-mapper.c:6562
+#: ../src/display.c:1077
 msgid ""
 "It looks like this is your first time running Maemo Mapper.  Press OK to "
 "view the the help pages. Otherwise, press Cancel to continue."
 msgstr ""
 
-#: ../src/maemo-mapper.c:5094
-msgid "Keep Display On Only in Fullscreen Mode"
-msgstr "Не спирай дисплей само в пълноекранен режим"
-
-#: ../src/maemo-mapper.c:8592 ../src/maemo-mapper.c:12661
-#: ../src/maemo-mapper.c:12950 ../src/maemo-mapper.c:13177
+#: ../src/poi.c:453 ../src/poi.c:615 ../src/poi.c:912 ../src/poi.c:1151
+#: ../src/poi.c:1757
 msgid "Label"
 msgstr "Етикет"
 
-#: ../src/maemo-mapper.c:3003
+#: ../src/poi.c:160
 msgid "Landmark"
 msgstr ""
 
-#: ../src/maemo-mapper.c:13161 ../src/maemo-mapper.c:13424
+#: ../src/display.c:2426 ../src/poi.c:1135
 #, fuzzy
 msgid "Lat"
 msgstr "Шир/Дълж"
 
-#: ../src/maemo-mapper.c:10503 ../src/maemo-mapper.c:13611
+#: ../src/menu.c:300 ../src/path.c:1344
 #, fuzzy
 msgid "Lat, Lon:"
 msgstr "Шир, Дълж"
 
-#: ../src/maemo-mapper.c:6231
+#: ../src/menu.c:1544
 msgid "Lat/Lon"
 msgstr "Шир/Дълж"
 
-#: ../src/maemo-mapper.c:6254
+#: ../src/menu.c:1487
 #, fuzzy
 msgid "Lat/Lon..."
 msgstr "Шир/Дълж..."
 
-#: ../src/maemo-mapper.c:2786 ../src/maemo-mapper.c:10816
-#: ../src/maemo-mapper.c:12141 ../src/maemo-mapper.c:13512
+#: ../src/cmenu.c:82 ../src/display.c:778 ../src/maps.c:2142 ../src/menu.c:741
 msgid "Latitude"
 msgstr "Ширина"
 
-#: ../src/maemo-mapper.c:6237
+#: ../src/menu.c:1550
 msgid "Lead"
 msgstr "Изпреварващо"
 
-#: ../src/maemo-mapper.c:5011
+#: ../src/settings.c:1078
 msgid "Lead Amount"
 msgstr "Изпрев. дължина"
 
-#: ../src/maemo-mapper.c:5082
+#: ../src/main.c:196 ../src/menu.c:1468
+#, fuzzy
+msgid "Left"
+msgstr "Горе/Ляво"
+
+#: ../src/settings.c:1151
 msgid "Line Width"
 msgstr "Дебелина"
 
-#: ../src/maemo-mapper.c:2831
+#: ../src/display.c:823
 msgid "Local time"
 msgstr "Местно време"
 
-#: ../src/maemo-mapper.c:5162 ../src/maemo-mapper.c:6409
-#: ../src/maemo-mapper.c:8587
+#: ../src/cmenu.c:592 ../src/poi.c:448 ../src/settings.c:1249
 msgid "Location"
 msgstr "Позиция"
 
-#: ../src/maemo-mapper.c:2997
+#: ../src/poi.c:154
 msgid "Lodging"
 msgstr ""
 
-#: ../src/maemo-mapper.c:13169 ../src/maemo-mapper.c:13433
+#: ../src/display.c:2435 ../src/poi.c:1143
 #, fuzzy
 msgid "Lon"
 msgstr "Шир/Дълж"
 
-#: ../src/maemo-mapper.c:2795 ../src/maemo-mapper.c:10829
-#: ../src/maemo-mapper.c:12145 ../src/maemo-mapper.c:13513
+#: ../src/cmenu.c:83 ../src/display.c:787 ../src/maps.c:2146 ../src/menu.c:755
 msgid "Longitude"
 msgstr "Дължина"
 
-#: ../src/maemo-mapper.c:4484 ../src/maemo-mapper.c:4968
+#: ../src/settings.c:531
 msgid "MAC"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11470
+#: ../src/settings.c:1009
+#, fuzzy
+msgid "MAC Address"
+msgstr "Добави"
+
+#: ../src/maps.c:1498
 msgid ""
 "Maemo Mapper will now download and add a list of possibly-duplicate "
 "repositories from the internet.  Continue?"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12033
+#: ../src/maps.c:2034
 msgid "Manage Maps"
 msgstr "Управление Карти"
 
-#: ../src/maemo-mapper.c:6168
+#: ../src/menu.c:1415
 msgid "Manage Maps..."
 msgstr "Управление Карти..."
 
-#: ../src/maemo-mapper.c:11550
+#: ../src/maps.c:1578
 msgid "Manage Repositories"
 msgstr "Управление Хранилища"
 
-#: ../src/maemo-mapper.c:6170
+#: ../src/menu.c:1417
 msgid "Manage Repositories..."
 msgstr "Управление Хранилища..."
 
-#: ../src/maemo-mapper.c:2291
+#: ../src/display.c:283
 msgid "Manual"
 msgstr "Ръчно"
 
-#: ../src/maemo-mapper.c:6163
+#: ../src/menu.c:1410
 msgid "Maps"
 msgstr "Карти"
 
-#: ../src/maemo-mapper.c:2876
+#: ../src/display.c:868
 msgid "Max speed"
 msgstr "Макс. скорост"
 
-#: ../src/maemo-mapper.c:5078
+#: ../src/settings.c:1147
 msgid "Misc."
 msgstr "Други"
 
-#: ../src/maemo-mapper.c:5114
+#: ../src/settings.c:1204
 msgid "Misc. 2"
 msgstr "Други 2"
 
-#: ../src/maemo-mapper.c:3006
+#: ../src/poi.c:163
 msgid "Miscellaneous category for everything else."
 msgstr ""
 
-#: ../src/maemo-mapper.c:12285 ../src/maemo-mapper.c:12449
+#: ../src/maps.c:2294 ../src/menu.c:520
 #, fuzzy
 msgid ""
 "NOTE: You must set a Map URI in the current repository in order to download "
@@ -727,670 +905,761 @@ msgstr ""
 "Задайте URI на картов сървър в \"Управление на Хранилища\" за да изтегляте "
 "карти."
 
-#: ../src/maemo-mapper.c:11171 ../src/maemo-mapper.c:11409
+#: ../src/maps.c:1197 ../src/maps.c:1437
 msgid "Name"
 msgstr "Име"
 
-#: ../src/maemo-mapper.c:6262
+#: ../src/menu.c:1495
 #, fuzzy
 msgid "Nearest POI"
 msgstr "Избор POI"
 
-#: ../src/maemo-mapper.c:11161
+#: ../src/maps.c:1187
 msgid "New Name"
 msgstr "Ново Име"
 
-#: ../src/maemo-mapper.c:11399
+#: ../src/maps.c:1427
 msgid "New Repository"
 msgstr "Ново Хранилище"
 
-#: ../src/maemo-mapper.c:11589
+#: ../src/maps.c:1617
 msgid "New..."
 msgstr "Ново ..."
 
-#: ../src/maemo-mapper.c:6260
+#: ../src/menu.c:1493
 #, fuzzy
 msgid "Next Waypoint"
 msgstr "Точки по пътя"
 
-#: ../src/maemo-mapper.c:11362
+#: ../src/maps.c:1390
 msgid "Next-able"
 msgstr ""
 
-#: ../src/maemo-mapper.c:5283
+#: ../src/settings.c:1472
 #, fuzzy
 msgid ""
-"No GPS Receiver MAC provided.\n"
+"No GPS Receiver provided.\n"
 "GPS will be disabled."
 msgstr ""
 "Липсва MAC на приемник.\n"
 "Забранявам GPS."
 
-#: ../src/maemo-mapper.c:8530 ../src/maemo-mapper.c:11082
+#: ../src/menu.c:950 ../src/poi.c:391 ../src/poi.c:2772
 msgid "No POIs found."
 msgstr ""
 
-#: ../src/maemo-mapper.c:6243
+#: ../src/poi.c:1401
+msgid "No POIs were found."
+msgstr ""
+
+#: ../src/main.c:309 ../src/menu.c:1556
 msgid "None"
 msgstr "Не"
 
-#: ../src/maemo-mapper.c:4984
+#: ../src/menu.c:1473
 #, fuzzy
-msgid ""
-"Note: You can enter a device path\n"
-"(e.g. \"/dev/rfcomm0\")."
-msgstr ""
-"Note: For manual rfcomm, enter a device path\n"
-"(e.g. \"/dev/rfcomm0\")."
+msgid "North"
+msgstr "URI формат"
 
-#: ../src/maemo-mapper.c:6127 ../src/maemo-mapper.c:6147
+#: ../src/menu.c:1359 ../src/menu.c:1379
 msgid "Open..."
 msgstr "Отваряне..."
 
-#: ../src/maemo-mapper.c:6572
+#: ../src/display.c:1087
 msgid ""
 "OpenStreetMap.org provides public, free-to-use maps.  You can also download "
 "a sample set of repositories from  the internet by using the \"Download...\" "
 "button."
 msgstr ""
 
-#: ../src/maemo-mapper.c:10083
+#: ../src/path.c:1126 ../src/poi.c:2268 ../src/poi.c:2565
 msgid "Origin"
 msgstr "Начало"
 
-#: ../src/maemo-mapper.c:3005
+#: ../src/poi.c:162
 msgid "Other"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12075
+#: ../src/maps.c:2076
 msgid "Overwrite"
 msgstr "Подмяна стари"
 
-#: ../src/maemo-mapper.c:4792 ../src/maemo-mapper.c:5177
-#: ../src/maemo-mapper.c:6464
+#: ../src/cmenu.c:647 ../src/menu.c:1395 ../src/menu.c:1534
+#: ../src/settings.c:823 ../src/settings.c:1264
 msgid "POI"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12903
+#: ../src/poi.c:865
 msgid "POI Categories"
 msgstr "POI Категории"
 
-#: ../src/maemo-mapper.c:6222
-msgid "POI Categories..."
-msgstr "POI Категории..."
+#: ../src/poi.c:1987
+msgid "POI List"
+msgstr ""
 
-#: ../src/maemo-mapper.c:5181
+#: ../src/settings.c:1268
 msgid "POI database"
 msgstr "POI база данни"
 
-#: ../src/maemo-mapper.c:6218
-msgid "POIs"
+#: ../src/poi.c:1907
+msgid "POIs Exported"
+msgstr ""
+
+#: ../src/poi.c:1395
+msgid ""
+"POIs were added to the POI database.  The following screen will allow you to "
+"modify or delete any of the new POIs."
 msgstr ""
 
-#: ../src/maemo-mapper.c:2287
+#: ../src/display.c:279
 msgid "PPS"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8044
+#: ../src/poi.c:2252
+msgid "Page"
+msgstr ""
+
+#: ../src/menu.c:1460
+msgid "Pan"
+msgstr ""
+
+#: ../src/main.c:245
 msgid "Pan East"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8041
+#: ../src/main.c:242
 msgid "Pan North"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8043
+#: ../src/settings.c:1065
+#, fuzzy
+msgid "Pan Sensitivity"
+msgstr "Чувствителност"
+
+#: ../src/main.c:244
 msgid "Pan South"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8042
+#: ../src/main.c:243
 msgid "Pan West"
 msgstr ""
 
-#  This word refers to Pitch as in of a person's voice.
-#: ../src/maemo-mapper.c:5067
-msgid "Pitch"
-msgstr "Тон"
-
-#: ../src/maemo-mapper.c:2990
+#: ../src/poi.c:147
 msgid "Places to eat or drink."
 msgstr ""
 
-#: ../src/maemo-mapper.c:2992
+#: ../src/poi.c:149
 msgid "Places to shop or acquire services."
 msgstr ""
 
-#: ../src/maemo-mapper.c:2998
+#: ../src/poi.c:155
 msgid "Places to stay temporarily or for the night."
 msgstr ""
 
-#: ../src/maemo-mapper.c:10567
+#: ../src/menu.c:364
 #, fuzzy
 msgid "Please provide a description for the mark."
 msgstr "Моля посочете POI име."
 
-#: ../src/maemo-mapper.c:4519
+#: ../src/settings.c:566
 msgid "Please select a bluetooth device from the list."
 msgstr "Моля, изберете bluetooth устройство от списъка."
 
-#: ../src/maemo-mapper.c:13289
+#: ../src/poi.c:1250 ../src/poi.c:1532
 #, fuzzy
-msgid "Please specify a category for the POI."
+msgid "Please specify a category."
 msgstr "Моля посочете POI име."
 
-#: ../src/maemo-mapper.c:13282
-msgid "Please specify a name for the POI."
-msgstr "Моля посочете POI име."
+#: ../src/poi.c:2104 ../src/poi.c:2425
+#, fuzzy
+msgid "Please specify a default category."
+msgstr "Моля посочете име за категорията."
 
-#: ../src/maemo-mapper.c:12719
+#: ../src/poi.c:673
 msgid "Please specify a name for the category."
 msgstr "Моля посочете име за категорията."
 
-#: ../src/maemo-mapper.c:10173
+#: ../src/poi.c:1243
 #, fuzzy
-msgid "Please specify a source URL."
+msgid "Please specify a name."
 msgstr "Моля посочете POI име."
 
-#: ../src/maemo-mapper.c:10217
-msgid "Please specify a start location."
-msgstr "Моля задайте стартова точка."
+#: ../src/poi.c:2432
+#, fuzzy
+msgid "Please specify a query."
+msgstr "Моля посочете POI име."
 
-#: ../src/maemo-mapper.c:10941
+#: ../src/path.c:1214 ../src/poi.c:2368
 #, fuzzy
-msgid "Please specify an address."
+msgid "Please specify a source URL."
 msgstr "Моля посочете POI име."
 
-#: ../src/maemo-mapper.c:10224
+#: ../src/path.c:1256
+msgid "Please specify a start location."
+msgstr "Моля задайте стартова точка."
+
+#: ../src/path.c:1263
 msgid "Please specify an end location."
 msgstr "Моля задайте крайна точка."
 
-#: ../src/maemo-mapper.c:13340
-msgid "Problem adding POI"
-msgstr "Проблем при добавяне на POI"
-
-#: ../src/maemo-mapper.c:12756
-msgid "Problem adding category"
-msgstr "Проблем при добавяне категория"
-
-#: ../src/maemo-mapper.c:12567 ../src/maemo-mapper.c:13019
-msgid "Problem deleting POI"
-msgstr "Проблем при изтриване на POI"
-
-#: ../src/maemo-mapper.c:12576
-msgid "Problem deleting category"
-msgstr "Проблем при изтриване категория"
+#: ../src/poi.c:2419 ../src/poi.c:2696
+#, fuzzy
+msgid "Please specify an origin."
+msgstr "Моля задайте крайна точка."
 
-#: ../src/maemo-mapper.c:12795
-msgid "Problem updating Category"
-msgstr "Проблем при обновяване на Категория"
+#: ../src/settings.c:1110
+msgid "Points"
+msgstr ""
 
-#: ../src/maemo-mapper.c:13318
-msgid "Problem updating POI"
-msgstr "Проблем при обновяване на POI"
+#: ../src/settings.c:1035
+#, fuzzy
+msgid "Port"
+msgstr "URI формат"
 
-#: ../src/maemo-mapper.c:12741
-msgid "Problem updating category"
-msgstr "Проблем при обновяване на категория"
+#: ../src/maps.c:850
+msgid "Processing Maps"
+msgstr ""
 
-#: ../src/maemo-mapper.c:2946
-msgid "Problem with POI database"
-msgstr "Проблем с POI база данни"
+#: ../src/poi.c:2278 ../src/poi.c:2575
+msgid "Query"
+msgstr ""
 
-#: ../src/maemo-mapper.c:2288
+#: ../src/display.c:280
 msgid "Real Time Kinematic"
 msgstr ""
 
-#: ../src/maemo-mapper.c:3723
+#: ../src/path.c:919
 msgid "Really clear the track?"
 msgstr ""
 
-#: ../src/maemo-mapper.c:3678
+#: ../src/path.c:798
 msgid "Recalculating directions..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:2993
+#: ../src/poi.c:150
 #, fuzzy
 msgid "Recreation"
 msgstr "Позиция"
 
-#: ../src/maemo-mapper.c:11583
+#: ../src/maps.c:1611
 msgid "Rename..."
 msgstr "Преименуване..."
 
-#: ../src/maemo-mapper.c:11440
+#: ../src/maps.c:1468
 msgid "Replace all repositories with the default repository?"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6137
+#: ../src/menu.c:1369 ../src/menu.c:1452
 msgid "Reset"
 msgstr "Рестарт"
 
-#: ../src/maemo-mapper.c:6281 ../src/maemo-mapper.c:8069
+#: ../src/main.c:278 ../src/menu.c:1585
 msgid "Reset Bluetooth"
 msgstr "Рестарт Bluetooth"
 
-#: ../src/maemo-mapper.c:4699
+#: ../src/main.c:247
+msgid "Reset Viewing Angle"
+msgstr ""
+
+#: ../src/settings.c:730
 msgid "Reset all colors to their original defaults?"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4580
+#: ../src/settings.c:616
 msgid "Reset all hardware keys to their original defaults?"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4614 ../src/maemo-mapper.c:4735
-#: ../src/maemo-mapper.c:11561
+#: ../src/maps.c:1589 ../src/settings.c:650 ../src/settings.c:766
 #, fuzzy
 msgid "Reset..."
 msgstr "Рестарт"
 
-#: ../src/maemo-mapper.c:2987
+#: ../src/poi.c:144
 msgid "Residence"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4777 ../src/maemo-mapper.c:6123
-#: ../src/maemo-mapper.c:6204
+#: ../src/poi.c:146
+msgid "Restaurant"
+msgstr ""
+
+#: ../src/main.c:194 ../src/menu.c:1470
+#, fuzzy
+msgid "Right"
+msgstr "Долу/Дясно"
+
+#: ../src/menu.c:1444
+#, fuzzy
+msgid "Rotate"
+msgstr "Маршрут"
+
+#: ../src/settings.c:1097
+#, fuzzy
+msgid "Rotate Sensit."
+msgstr "Чувствителност"
+
+#: ../src/main.c:249
+msgid "Rotate View Clockwise"
+msgstr ""
+
+#: ../src/main.c:251
+msgid "Rotate View Counter-Clockwise"
+msgstr ""
+
+#: ../src/menu.c:1355 ../src/menu.c:1520 ../src/settings.c:808
 msgid "Route"
 msgstr "Маршрут"
 
-#: ../src/maemo-mapper.c:10311
+#: ../src/path.c:672
 msgid "Route Downloaded"
 msgstr "Маршрут изтеглен"
 
-#: ../src/maemo-mapper.c:8368 ../src/maemo-mapper.c:10360
+#: ../src/main.c:485 ../src/menu.c:119
 msgid "Route Opened"
 msgstr "Маршрут отворен"
 
-#: ../src/maemo-mapper.c:10615
+#: ../src/menu.c:150
 msgid "Route Saved"
 msgstr "Маршрут записан"
 
-#: ../src/maemo-mapper.c:10705
+#: ../src/menu.c:1048
 msgid "Routes are now hidden"
 msgstr "Маршрутите скрити"
 
-#: ../src/maemo-mapper.c:10699
+#: ../src/menu.c:1042
 msgid "Routes are now shown"
 msgstr "Маршрутите показани"
 
-#: ../src/maemo-mapper.c:2285
+#: ../src/display.c:277
 msgid "SPS"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2849
+#: ../src/display.c:841
 msgid "Sat in use"
 msgstr "Ползва сат."
 
-#: ../src/maemo-mapper.c:2840
+#: ../src/display.c:832
 msgid "Sat in view"
 msgstr "Виждими сат."
 
-#: ../src/maemo-mapper.c:2781
+#: ../src/display.c:773
 msgid "Satellites details"
 msgstr "Информация Сателити"
 
-#: ../src/maemo-mapper.c:2707
+#: ../src/display.c:699
 msgid "Satellites in view"
 msgstr "Видими сателити"
 
-#: ../src/maemo-mapper.c:6131 ../src/maemo-mapper.c:6149
+#: ../src/menu.c:1363 ../src/menu.c:1381
 msgid "Save..."
 msgstr "Записване..."
 
-#: ../src/maemo-mapper.c:6199
+#: ../src/menu.c:1510
 msgid "Scale"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4978
+#: ../src/settings.c:1019
 msgid "Scan..."
 msgstr "Скан..."
 
-#: ../src/maemo-mapper.c:4495
+#: ../src/settings.c:542
 msgid "Scanning for Bluetooth Devices"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2999
+#: ../src/poi.c:156
 msgid "School"
 msgstr ""
 
-#: ../src/maemo-mapper.c:3138
+#: ../src/gps.c:790
 msgid "Searching for GPS receiver"
 msgstr "Търси GPS приемник"
 
-#: ../src/maemo-mapper.c:4459
+#: ../src/settings.c:506
 msgid "Select Bluetooth Device"
 msgstr "Избор Bluetooth устрийство"
 
-#: ../src/maemo-mapper.c:8054
+#: ../src/main.c:263
 #, fuzzy
 msgid "Select Next Repository"
 msgstr "Следващо Хранилище"
 
-#: ../src/maemo-mapper.c:8560
+#: ../src/poi.c:421
 msgid "Select POI"
 msgstr "Избор POI"
 
-#: ../src/maemo-mapper.c:8630
+#: ../src/poi.c:1933
+msgid ""
+"Select an operation to perform\n"
+"on the POIs that you checked\n"
+"in the POI list."
+msgstr ""
+
+#: ../src/poi.c:486
 msgid "Select one POI from the list."
 msgstr "Избор на една POI от списъка."
 
-#: ../src/maemo-mapper.c:4998
-msgid "Sensitivity"
-msgstr "Чувствителност"
+#: ../src/poi.c:142
+#, fuzzy
+msgid "Service Station"
+msgstr "Позиция"
+
+#: ../src/poi.c:1502 ../src/poi.c:1939
+#, fuzzy
+msgid "Set Category..."
+msgstr "Редакт. категории..."
 
-#: ../src/maemo-mapper.c:6431
+#: ../src/cmenu.c:614
 #, fuzzy
 msgid "Set as GPS Location"
 msgstr "Използвай GPS позиция"
 
-#: ../src/maemo-mapper.c:4940
+#: ../src/settings.c:980
 #, fuzzy
 msgid "Settings"
 msgstr "Настройки..."
 
-#: ../src/maemo-mapper.c:6288
+#: ../src/menu.c:1592
 msgid "Settings..."
 msgstr "Настройки..."
 
-#: ../src/maemo-mapper.c:12058
+#: ../src/maps.c:2059
 msgid "Setup"
 msgstr "Настройка"
 
-#: ../src/maemo-mapper.c:2991
+#: ../src/poi.c:148
 msgid "Shopping/Services"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6442
+#: ../src/menu.c:1501
+msgid "Show"
+msgstr ""
+
+#: ../src/cmenu.c:625
 msgid "Show Description"
 msgstr "Покажи Описание"
 
-#: ../src/maemo-mapper.c:6157 ../src/maemo-mapper.c:8064
+#: ../src/main.c:273 ../src/menu.c:1389
 #, fuzzy
 msgid "Show Distance from Beginning"
 msgstr "Покажи разстояние до"
 
-#: ../src/maemo-mapper.c:8062
+#: ../src/main.c:271
 #, fuzzy
 msgid "Show Distance from Last Break"
 msgstr "Покажи разстояние до"
 
-#: ../src/maemo-mapper.c:6155
+#: ../src/menu.c:1387
 #, fuzzy
 msgid "Show Distance from Last Mark"
 msgstr "Покажи разстояние до"
 
-#: ../src/maemo-mapper.c:6418 ../src/maemo-mapper.c:6449
-#: ../src/maemo-mapper.c:6473
+#: ../src/cmenu.c:601 ../src/cmenu.c:632 ../src/cmenu.c:656
 msgid "Show Distance to"
 msgstr "Покажи разстояние до"
 
-#: ../src/maemo-mapper.c:6135 ../src/maemo-mapper.c:8058
+#: ../src/main.c:267 ../src/menu.c:1367
 #, fuzzy
 msgid "Show Distance to End of Route"
 msgstr "Покажи разстояние до"
 
-#: ../src/maemo-mapper.c:6133 ../src/maemo-mapper.c:8056
+#: ../src/main.c:265 ../src/menu.c:1365
 #, fuzzy
 msgid "Show Distance to Next Waypoint"
 msgstr "Разстояние до точка по пътя"
 
-#: ../src/maemo-mapper.c:6274
+#: ../src/menu.c:1578
 msgid "Show Information"
 msgstr "Покажи Информация"
 
-#: ../src/maemo-mapper.c:6415 ../src/maemo-mapper.c:6440
+#: ../src/cmenu.c:598 ../src/cmenu.c:623
 msgid "Show Lat/Lon"
 msgstr "Покажи Шир/Дълж"
 
-#: ../src/maemo-mapper.c:5196
+#: ../src/settings.c:1283
 msgid "Show POI below zoom"
 msgstr "Показвай POI под мащаб"
 
-#: ../src/maemo-mapper.c:13414
+#: ../src/display.c:2416
 #, fuzzy
 msgid "Show Position"
 msgstr "Покажи Описание"
 
-#: ../src/maemo-mapper.c:2292
+#: ../src/display.c:284
 msgid "Simulation"
 msgstr "Симулация"
 
-#: ../src/maemo-mapper.c:10049
+#: ../src/path.c:1086 ../src/poi.c:2220
 msgid "Source URL"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2804 ../src/maemo-mapper.c:5055
+#: ../src/menu.c:1475
+#, fuzzy
+msgid "South"
+msgstr "относно"
+
+#: ../src/display.c:796
 msgid "Speed"
 msgstr "Скорост"
 
-#: ../src/maemo-mapper.c:5152
+#: ../src/settings.c:1239
 #, fuzzy
 msgid "Speed Limit"
 msgstr "Скорост"
 
-#: ../src/maemo-mapper.c:2986
+#: ../src/poi.c:143
 msgid "Stations for purchasing fuel for vehicles."
 msgstr ""
 
-#: ../src/maemo-mapper.c:3399
+#: ../src/maps.c:504
+msgid ""
+"The current repository is in a legacy format and will be converted.  You "
+"should delete your old maps if you no longer plan to use them."
+msgstr ""
+
+#: ../src/path.c:551
 msgid "The current route is empty."
 msgstr ""
 
-#: ../src/maemo-mapper.c:3445 ../src/maemo-mapper.c:3460
+#: ../src/path.c:597 ../src/path.c:612
 msgid "The current track is empty."
 msgstr ""
 
-#: ../src/maemo-mapper.c:4660
+#: ../src/settings.c:696
 msgid "The following action is mapped to multiple keys"
 msgstr ""
 
-#: ../src/maemo-mapper.c:9002
+#: ../src/input.c:364
 msgid "There are no other next-able repositories."
 msgstr ""
 
-#: ../src/maemo-mapper.c:13853
+#: ../src/cmenu.c:265 ../src/cmenu.c:287 ../src/cmenu.c:306 ../src/cmenu.c:326
+#: ../src/cmenu.c:345 ../src/cmenu.c:364 ../src/cmenu.c:442 ../src/cmenu.c:461
 msgid "There are no waypoints."
 msgstr ""
 
-#: ../src/maemo-mapper.c:3380 ../src/maemo-mapper.c:11044
+#: ../src/menu.c:912 ../src/path.c:532
 msgid "There is no next waypoint."
 msgstr ""
 
-#: ../src/maemo-mapper.c:8046
+#: ../src/main.c:253
 #, fuzzy
 msgid "Toggle Auto-Center"
 msgstr "Авто-Центр."
 
-#: ../src/maemo-mapper.c:8048
+#: ../src/main.c:255
+#, fuzzy
+msgid "Toggle Auto-Rotate"
+msgstr "Авто-Центр."
+
+#: ../src/main.c:257
 #, fuzzy
 msgid "Toggle Fullscreen"
 msgstr "Пълноекранно"
 
-#: ../src/maemo-mapper.c:8065
+#: ../src/main.c:274
 msgid "Toggle GPS"
 msgstr "Вкл/изкл GPS"
 
-#: ../src/maemo-mapper.c:8066
+#: ../src/main.c:275
 msgid "Toggle GPS Info"
 msgstr "Вкл/изкл GPS инфо"
 
-#: ../src/maemo-mapper.c:8053
+#: ../src/main.c:262
 #, fuzzy
 msgid "Toggle POIs"
 msgstr "Вкл/изкл GPS"
 
-#: ../src/maemo-mapper.c:8052
+#: ../src/main.c:261
 #, fuzzy
 msgid "Toggle Scale"
 msgstr "Вкл/изкл GPS"
 
-#: ../src/maemo-mapper.c:8068
+#: ../src/main.c:277
 msgid "Toggle Speed Limit"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8051
+#: ../src/main.c:260
 msgid "Toggle Tracks"
 msgstr "Вкл/изкл Път"
 
-#: ../src/maemo-mapper.c:8095 ../src/maemo-mapper.c:12186
+#: ../src/main.c:304 ../src/maps.c:2187
 msgid "Top-Left"
 msgstr "Горе/Ляво"
 
-#: ../src/maemo-mapper.c:8096
+#: ../src/main.c:305
 #, fuzzy
 msgid "Top-Right"
 msgstr "Долу/Дясно"
 
-#: ../src/maemo-mapper.c:4762 ../src/maemo-mapper.c:6143
-#: ../src/maemo-mapper.c:6209
+#: ../src/menu.c:1375 ../src/menu.c:1525 ../src/settings.c:793
 msgid "Track"
 msgstr "Път"
 
-#: ../src/maemo-mapper.c:10434
+#: ../src/menu.c:231
 msgid "Track Opened"
 msgstr "Път отворен"
 
-#: ../src/maemo-mapper.c:10456
+#: ../src/menu.c:253
 msgid "Track Saved"
 msgstr "Път записан"
 
-#: ../src/maemo-mapper.c:10655
+#: ../src/menu.c:985
 msgid "Tracks are now hidden"
 msgstr "Пътеки скрити"
 
-#: ../src/maemo-mapper.c:10649
+#: ../src/menu.c:979
 msgid "Tracks are now shown"
 msgstr "Пътеки показани"
 
-#: ../src/maemo-mapper.c:2995
+#: ../src/poi.c:152
 msgid "Transportation"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11278
+#: ../src/maps.c:1304
 msgid "URL Format"
 msgstr "URI формат"
 
-#: ../src/maemo-mapper.c:5543
-msgid "Unable to create cache directory for repository"
+#: ../src/maps.c:684
+msgid "Unable to create map database for repository"
 msgstr ""
 
-#: ../src/maemo-mapper.c:5118
+#: ../src/settings.c:1162
+#, fuzzy
+msgid "Unblank Screen"
+msgstr "Пълноекранно"
+
+#: ../src/settings.c:1191
 msgid "Units"
 msgstr "Единици"
 
-#: ../src/maemo-mapper.c:11003
+#: ../src/util.c:155
 msgid "Unknown error while locating address."
 msgstr ""
 
-#: ../src/maemo-mapper.c:10070
+#: ../src/main.c:193 ../src/menu.c:1464
+msgid "Up"
+msgstr ""
+
+#: ../src/path.c:1103 ../src/poi.c:2233 ../src/poi.c:2531
 msgid "Use End of Route"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10060
+#: ../src/path.c:1097 ../src/poi.c:2227 ../src/poi.c:2525
 msgid "Use GPS Location"
 msgstr "Използвай GPS позиция"
 
-#: ../src/maemo-mapper.c:6214
+#: ../src/menu.c:1530
 msgid "Velocity Vector"
 msgstr "Вектор скорост"
 
-#: ../src/maemo-mapper.c:6181
+#: ../src/menu.c:1428
 msgid "View"
 msgstr "Изглед"
 
-#: ../src/maemo-mapper.c:12167
+#: ../src/maps.c:2168
 msgid "View Center"
 msgstr "Видим център"
 
-#: ../src/maemo-mapper.c:11333
+#: ../src/maps.c:1361
 msgid "View Zoom Steps"
 msgstr "Преглед Мащаб Стъпки"
 
-#: ../src/maemo-mapper.c:6470
+#: ../src/cmenu.c:653
 msgid "View/Edit..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:12554
+#: ../src/poi.c:508
 msgid "WARNING: All POIs in that category will also be deleted!"
 msgstr "ВНИМАНИЕ: Всияки POI в Категорията ще бъдат изтрити!"
 
-#: ../src/maemo-mapper.c:6435
+#: ../src/cmenu.c:618
 msgid "Waypoint"
 msgstr "Точки по пътя"
 
-#: ../src/maemo-mapper.c:6579
+#: ../src/menu.c:1477
+#, fuzzy
+msgid "West"
+msgstr "Рестарт"
+
+#: ../src/display.c:1094
 msgid ""
 "You will now see a blank screen.  You can download maps using the \"Manage "
 "Maps\" menu item in the \"Maps\" menu.  Or, press OK to enable Auto-Download."
 msgstr ""
 
-#: ../src/maemo-mapper.c:12115
+#: ../src/maps.c:2116 ../src/menu.c:1434
 msgid "Zoom"
 msgstr "Мащаб"
 
-#: ../src/maemo-mapper.c:6185 ../src/maemo-mapper.c:8049
+#: ../src/main.c:258 ../src/menu.c:1438
 #, fuzzy
 msgid "Zoom In"
 msgstr "Мащаб"
 
-#: ../src/maemo-mapper.c:6194
+#: ../src/menu.c:1505
 #, fuzzy
 msgid "Zoom Level"
 msgstr "Мащаб"
 
-#: ../src/maemo-mapper.c:12121
+#: ../src/maps.c:2122
 msgid "Zoom Levels to Download: (0 = most detail)"
 msgstr "Мащаб нива за изтегляне: (0 = най-детайлно)"
 
-#: ../src/maemo-mapper.c:6187 ../src/maemo-mapper.c:8050
+#: ../src/main.c:259 ../src/menu.c:1440
 #, fuzzy
 msgid "Zoom Out"
 msgstr "Мащаб"
 
-#: ../src/maemo-mapper.c:8815 ../src/maemo-mapper.c:8928
-#: ../src/maemo-mapper.c:12356 ../src/maemo-mapper.c:12374
+#: ../src/input.c:103 ../src/input.c:290 ../src/menu.c:546 ../src/menu.c:564
 msgid "Zoom to Level"
 msgstr "Мащаб"
 
-#: ../src/maemo-mapper.c:11890 ../src/maemo-mapper.c:11897
+#: ../src/maps.c:1880 ../src/maps.c:1887
 msgid "about"
 msgstr "относно"
 
-#: ../src/maemo-mapper.c:2708
+#: ../src/display.c:700
 msgid "in use"
 msgstr "в употреба"
 
-#: ../src/maemo-mapper.c:7999
+#: ../src/main.c:189
 msgid "km"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11810 ../src/maemo-mapper.c:11898
+#: ../src/maps.c:1791 ../src/maps.c:1888
 msgid "maps"
 msgstr "карти"
 
-#: ../src/maemo-mapper.c:11804 ../src/maemo-mapper.c:11891
+#: ../src/maps.c:1785 ../src/maps.c:1881
 msgid "maps "
 msgstr "карти"
 
-#: ../src/maemo-mapper.c:8000
+#: ../src/display.c:1466
+msgid "maps failed to download."
+msgstr ""
+
+#: ../src/main.c:190
 msgid "mi."
 msgstr ""
 
-#: ../src/maemo-mapper.c:8001
+#: ../src/main.c:191
 msgid "n.m."
 msgstr ""
 
-#: ../src/maemo-mapper.c:2862
+#: ../src/display.c:854
 msgid "nofix"
 msgstr "не фикс"
 
-#: ../src/maemo-mapper.c:2293 ../src/maemo-mapper.c:2871
+#: ../src/display.c:285 ../src/display.c:863
 msgid "none"
 msgstr "няма"
 
-#: ../src/maemo-mapper.c:11810 ../src/maemo-mapper.c:11898
+#: ../src/maps.c:1791 ../src/maps.c:1888
 msgid "up to about"
 msgstr "до около"
 
+#~ msgid "Add"
+#~ msgstr "Добави"
+
 #~ msgid "Category List"
 #~ msgstr "Списък категории"
 
@@ -1413,6 +1682,9 @@ msgstr "до около"
 #~ msgid "Defaults"
 #~ msgstr "Възстановяване"
 
+#~ msgid "Delete"
+#~ msgstr "Изтриване"
+
 #~ msgid "Desc."
 #~ msgstr "Опис."
 
@@ -1422,9 +1694,15 @@ msgstr "до около"
 #~ msgid "Distance to Location"
 #~ msgstr "Разстояние до Локация"
 
+#~ msgid "Downloading maps"
+#~ msgstr "Изтегляне карти"
+
 #~ msgid "GPS Mark"
 #~ msgstr "GPS знак"
 
+#~ msgid "Keep Display On Only in Fullscreen Mode"
+#~ msgstr "Не спирай дисплей само в пълноекранен режим"
+
 #~ msgid "Label: "
 #~ msgstr "Етикет: "
 
@@ -1441,6 +1719,21 @@ msgstr "до около"
 #~ msgid "No waypoints found."
 #~ msgstr "Няма видими точки по пътя."
 
+#, fuzzy
+#~ msgid ""
+#~ "Note: You can enter a device path\n"
+#~ "(e.g. \"/dev/rfcomm0\")."
+#~ msgstr ""
+#~ "Note: For manual rfcomm, enter a device path\n"
+#~ "(e.g. \"/dev/rfcomm0\")."
+
+#  This word refers to Pitch as in of a person's voice.
+#~ msgid "Pitch"
+#~ msgstr "Тон"
+
+#~ msgid "Please specify a name for the POI."
+#~ msgstr "Моля посочете POI име."
+
 #~ msgid "Repositories"
 #~ msgstr "Хранилища"
 
index a9c79fd26059bacc50f2d0f8b97de5c8fa6cfee0..50c0b3f0a4dac3d284c90d0fc642c6bb1b487c4b 100644 (file)
@@ -11,7 +11,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: maemo-mapper 1.2.4\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-07-07 20:45-0400\n"
+"POT-Creation-Date: 2007-11-01 15:35-0400\n"
 "PO-Revision-Date: 2006-10-28 22:19-0400\n"
 "Last-Translator: John Costigan <gnuite@gmail.com>\n"
 "Language-Team: John Costigan <gnuite@gmail.com>\n"
@@ -19,77 +19,77 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: ../src/maemo-mapper.c:12960
+#: ../src/poi.c:922
 msgid "# POIs"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6293
+#: ../src/menu.c:1597
 msgid "About..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:12916
-msgid "Add"
-msgstr ""
-
-#: ../src/maemo-mapper.c:12650
+#: ../src/poi.c:604
 msgid "Add Category"
 msgstr ""
 
-#: ../src/maemo-mapper.c:13149
+#: ../src/poi.c:1123
 msgid "Add POI"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6427 ../src/maemo-mapper.c:6456
+#: ../src/cmenu.c:610 ../src/cmenu.c:639
 msgid "Add POI..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:6423 ../src/maemo-mapper.c:6478
+#: ../src/cmenu.c:606 ../src/cmenu.c:661
 msgid "Add Route Point"
 msgstr ""
 
-#: ../src/maemo-mapper.c:13601
+#: ../src/path.c:1334
 msgid "Add Waypoint"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6425 ../src/maemo-mapper.c:6480
+#: ../src/cmenu.c:608 ../src/cmenu.c:663
 msgid "Add Waypoint..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:10910
+#: ../src/poi.c:878
+msgid "Add..."
+msgstr ""
+
+#: ../src/menu.c:837
 msgid "Address"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10987
+#: ../src/menu.c:862
 msgid "Address Located"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6256
+#: ../src/menu.c:1489
 msgid "Address..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:5029
+#: ../src/settings.c:1126
 msgid "Advance Notice"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12100
+#: ../src/maps.c:2101
 msgid "Along Route - Radius (tiles):"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2813
+#: ../src/display.c:805
 msgid "Altitude"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4501
+#: ../src/settings.c:548
 msgid "An error occurred while attempting to scan for bluetooth devices."
 msgstr ""
 
-#: ../src/maemo-mapper.c:11489
+#: ../src/maps.c:1517
 msgid ""
 "An error occurred while retrieving the repositories.  The web service may be "
 "temporarily down."
 msgstr ""
 
-#: ../src/maemo-mapper.c:8829
+#: ../src/gps.c:955
 msgid ""
 "An error occurred while trying to reset the bluetooth radio.\n"
 "\n"
@@ -97,1229 +97,1450 @@ msgid ""
 "the /etc/sudoers file?"
 msgstr ""
 
-#: ../src/maemo-mapper.c:5025
+#: ../src/settings.c:1122
 msgid "Announce"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12137
+#: ../src/maps.c:2138
 msgid "Area"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4994 ../src/maemo-mapper.c:6227
+#: ../src/menu.c:1540 ../src/settings.c:1061
 msgid "Auto-Center"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10774
+#: ../src/menu.c:1114
 msgid "Auto-Center Mode: Lat/Lon"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10759
+#: ../src/menu.c:1097
 msgid "Auto-Center Mode: Lead"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10788
+#: ../src/menu.c:1130
 msgid "Auto-Center Off"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6172
+#: ../src/menu.c:1419
 msgid "Auto-Download"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10064
+#: ../src/settings.c:1221
+msgid "Auto-Download Pre-cache"
+msgstr ""
+
+#: ../src/menu.c:1454
+msgid "Auto-Rotate"
+msgstr ""
+
+#: ../src/menu.c:624
+msgid "Auto-Rotate Disabled"
+msgstr ""
+
+#: ../src/menu.c:619
+msgid "Auto-Rotate Enabled"
+msgstr ""
+
+#: ../src/path.c:1113
 msgid "Auto-Update"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10076
+#: ../src/path.c:1119
 msgid "Avoid Highways"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8098
+#: ../src/poi.c:1749
+msgid "Bear."
+msgstr ""
+
+#: ../src/main.c:310
+msgid "Bluetooth"
+msgstr ""
+
+#: ../src/main.c:307
 msgid "Bottom-Left"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8097 ../src/maemo-mapper.c:12208
+#: ../src/main.c:306 ../src/maps.c:2209
 msgid "Bottom-Right"
 msgstr ""
 
-#: ../src/maemo-mapper.c:3767
+#: ../src/path.c:967
 msgid "Break already inserted."
 msgstr ""
 
-#: ../src/maemo-mapper.c:5191 ../src/maemo-mapper.c:11297
+#: ../src/poi.c:2509
+msgid "Browse POIs"
+msgstr ""
+
+#: ../src/maps.c:1323 ../src/menu.c:1403 ../src/settings.c:1054
+#: ../src/settings.c:1278
 msgid "Browse..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:2996
+#: ../src/poi.c:153
 msgid "Bus stops, airports, train stations, etc."
 msgstr ""
 
-#: ../src/maemo-mapper.c:3001
+#: ../src/poi.c:158
 msgid "Business"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12091
+#: ../src/maps.c:2092
 msgid "By Area (see tab)"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11287
-msgid "Cache Dir."
+#: ../src/maps.c:1313
+msgid "Cache DB"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11227
+#: ../src/maps.c:1253
 msgid ""
 "Cannot delete the last repository - there must be at lease one repository."
 msgstr ""
 
-#: ../src/maemo-mapper.c:12416
+#: ../src/menu.c:1177
 msgid ""
-"Cannot enable GPS until a GPS Receiver MAC is set in the Settings dialog box."
+"Cannot enable GPS until a GPS receiver is set up in the Settings dialog box."
+msgstr ""
+
+#: ../src/menu.c:1405
+msgid "Categories..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:8597 ../src/maemo-mapper.c:13185
+#: ../src/poi.c:458 ../src/poi.c:1159 ../src/poi.c:1512 ../src/poi.c:1732
+#: ../src/poi.c:2089 ../src/poi.c:2243 ../src/poi.c:2540
 msgid "Category"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6139 ../src/maemo-mapper.c:6159
-#: ../src/maemo-mapper.c:12044
+#: ../src/poi.c:1928 ../src/poi.c:2003
+msgid "Checked POI Actions..."
+msgstr ""
+
+#: ../src/maps.c:2045 ../src/menu.c:1371 ../src/menu.c:1391
 msgid "Clear"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8060
+#: ../src/main.c:269
 msgid "Clear Track"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6295
+#: ../src/menu.c:1448
+msgid "Clockwise"
+msgstr ""
+
+#: ../src/menu.c:1599
 msgid "Close"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4729
+#: ../src/settings.c:760
 msgid "Colors"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4953
+#: ../src/settings.c:993
 msgid "Colors..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:11803 ../src/maemo-mapper.c:11890
+#: ../src/menu.c:1515
+msgid "Compass Rose"
+msgstr ""
+
+#: ../src/maps.c:1784 ../src/maps.c:1880
 msgid "Confirm DELETION of"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11234
+#: ../src/maps.c:1260
 msgid "Confirm delete of repository"
 msgstr ""
 
-#: ../src/maemo-mapper.c:13966
+#: ../src/cmenu.c:385
 msgid "Confirm delete of waypoint"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11809 ../src/maemo-mapper.c:11896
+#: ../src/maps.c:1790 ../src/maps.c:1886
 msgid "Confirm download of"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4663
+#: ../src/settings.c:699
 msgid "Continue?"
 msgstr ""
 
-#: ../src/maemo-mapper.c:13451
+#: ../src/display.c:2453
 msgid "Copy"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6446
+#: ../src/cmenu.c:629
 msgid "Copy Description"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6444
+#: ../src/cmenu.c:627
 msgid "Copy Lat/Lon"
 msgstr ""
 
-#: ../src/maemo-mapper.c:13684
+#: ../src/menu.c:1450
+msgid "Counter"
+msgstr ""
+
+#: ../src/path.c:1417
 msgid ""
 "Creating a \"waypoint\" with no description actually adds a break point.  Is "
 "that what you want?"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2286
+#: ../src/display.c:278
 msgid "DGPS"
 msgstr ""
 
-#: ../src/maemo-mapper.c:5129
-msgid "Degrees Format"
+#: ../src/poi.c:2079
+msgid "Default Category"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12631 ../src/maemo-mapper.c:13124
-msgid "Delete"
+#: ../src/settings.c:1208
+msgid "Degrees Format"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12081
+#: ../src/maps.c:2082
 msgid "Delete Maps"
 msgstr ""
 
-#: ../src/maemo-mapper.c:13008
+#: ../src/poi.c:958
 msgid "Delete POI?"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12552
+#: ../src/poi.c:506
 msgid "Delete category?"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6453 ../src/maemo-mapper.c:11586
+#: ../src/poi.c:1843
+msgid "Delete selected POI?"
+msgstr ""
+
+#: ../src/cmenu.c:636 ../src/maps.c:1614 ../src/poi.c:585 ../src/poi.c:1096
+#: ../src/poi.c:1943
 msgid "Delete..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:4489 ../src/maemo-mapper.c:10513
-#: ../src/maemo-mapper.c:12669 ../src/maemo-mapper.c:12955
-#: ../src/maemo-mapper.c:13212 ../src/maemo-mapper.c:13626
+#: ../src/menu.c:310 ../src/path.c:1359 ../src/poi.c:623 ../src/poi.c:917
+#: ../src/poi.c:1174 ../src/settings.c:536
 msgid "Description"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10093
+#: ../src/path.c:1136
 msgid "Destination"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6278
+#: ../src/menu.c:1582
 msgid "Details..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:2989
-msgid "Dining"
+#: ../src/gps.c:779
+msgid "Disconnecting from GPS receiver"
+msgstr ""
+
+#: ../src/poi.c:1740
+msgid "Dist."
 msgstr ""
 
-#: ../src/maemo-mapper.c:3365 ../src/maemo-mapper.c:3425
-#: ../src/maemo-mapper.c:13566
+#: ../src/cmenu.c:136 ../src/path.c:517 ../src/path.c:577
 msgid "Distance"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11354
+#: ../src/maps.c:1382
 msgid "Double Pixels"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12068
+#: ../src/main.c:195 ../src/menu.c:1466
+msgid "Down"
+msgstr ""
+
+#: ../src/maps.c:2069
 msgid "Download Maps"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10034
+#: ../src/poi.c:2202
+msgid "Download POIs"
+msgstr ""
+
+#: ../src/path.c:1071
 msgid "Download Route"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6420 ../src/maemo-mapper.c:6451
-#: ../src/maemo-mapper.c:6475
+#: ../src/cmenu.c:603 ../src/cmenu.c:634 ../src/cmenu.c:658
 msgid "Download Route to..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:11317
+#: ../src/maps.c:1345
 msgid "Download Zoom Steps"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6129 ../src/maemo-mapper.c:11567
+#: ../src/maps.c:1595 ../src/menu.c:1361 ../src/menu.c:1401
 msgid "Download..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:6937
-msgid "Downloading maps"
+#: ../src/maps.c:654 ../src/maps.c:667
+msgid "Downloaded maps will not be cached."
 msgstr ""
 
-#: ../src/maemo-mapper.c:12913
-msgid "Edit"
+#: ../src/menu.c:1479
+msgid "East"
 msgstr ""
 
-#: ../src/maemo-mapper.c:13208
+#: ../src/poi.c:1170
 msgid "Edit Categories..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:12625
+#: ../src/poi.c:579
 msgid "Edit Category"
 msgstr ""
 
-#: ../src/maemo-mapper.c:13118
+#: ../src/poi.c:1090
 msgid "Edit POI"
 msgstr ""
 
-#: ../src/maemo-mapper.c:3000
+#: ../src/poi.c:875 ../src/poi.c:1999
+msgid "Edit..."
+msgstr ""
+
+#: ../src/poi.c:157
 msgid "Elementary schools, college campuses, etc."
 msgstr ""
 
-#: ../src/maemo-mapper.c:6270
+#: ../src/menu.c:1574
 msgid "Enable GPS"
 msgstr ""
 
-#: ../src/maemo-mapper.c:5042
+#: ../src/settings.c:1139
 msgid "Enable Voice Synthesis (requires flite)"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12693 ../src/maemo-mapper.c:12945
+#: ../src/poi.c:647 ../src/poi.c:907
 msgid "Enabled"
 msgstr ""
 
-#: ../src/maemo-mapper.c:7185
-msgid ""
-"Error in download.  Check internet connection and/or Map Repository URL "
-"Format."
+#: ../src/poi.c:1305
+msgid "Error adding POI"
+msgstr ""
+
+#: ../src/poi.c:710
+msgid "Error adding category"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8371 ../src/maemo-mapper.c:10319
-#: ../src/maemo-mapper.c:10363 ../src/maemo-mapper.c:10437
+#: ../src/gps.c:631
+msgid "Error connecting to GPS receiver."
+msgstr ""
+
+#: ../src/gps.c:617
+msgid "Error connecting to GPSD."
+msgstr ""
+
+#: ../src/poi.c:521 ../src/poi.c:969 ../src/poi.c:1871
+msgid "Error deleting POI"
+msgstr ""
+
+#: ../src/poi.c:530
+msgid "Error deleting category"
+msgstr ""
+
+#: ../src/main.c:488 ../src/menu.c:122 ../src/menu.c:234 ../src/path.c:678
+#: ../src/poi.c:2130 ../src/poi.c:2481
 msgid "Error parsing GPX file."
 msgstr ""
 
-#: ../src/maemo-mapper.c:1501
+#: ../src/gps.c:667
+msgid "Error reading GPS data."
+msgstr ""
+
+#: ../src/poi.c:754
+msgid "Error updating Category"
+msgstr ""
+
+#: ../src/poi.c:1285 ../src/poi.c:1583
+msgid "Error updating POI"
+msgstr ""
+
+#: ../src/poi.c:695
+msgid "Error updating category"
+msgstr ""
+
+#: ../src/gpx.c:478 ../src/gpx.c:805
 msgid "Error while writing to file"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10459 ../src/maemo-mapper.c:10618
+#: ../src/poi.c:103
+msgid "Error with POI database"
+msgstr ""
+
+#: ../src/menu.c:153 ../src/menu.c:256 ../src/poi.c:1911
 msgid "Error writing GPX file."
 msgstr ""
 
-#: ../src/maemo-mapper.c:3148
+#: ../src/gps.c:801
 msgid "Establishing GPS fix"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2290
+#: ../src/display.c:282
 msgid "Estimated"
 msgstr ""
 
-#: ../src/maemo-mapper.c:3903
-msgid "Failed to connect to GPS receiver.  Retry?"
+#: ../src/poi.c:1948
+msgid "Export to GPX..."
+msgstr ""
+
+#: ../src/gps.c:923
+msgid "Failed to connect to Bluetooth GPS receiver."
 msgstr ""
 
-#: ../src/maemo-mapper.c:10251 ../src/maemo-mapper.c:10957
+#: ../src/util.c:139
 msgid "Failed to connect to GPX Directions server"
 msgstr ""
 
-#: ../src/maemo-mapper.c:5577
+#: ../src/settings.c:1646
 msgid "Failed to initialize GConf.  Quitting."
 msgstr ""
 
-#: ../src/maemo-mapper.c:4047
+#: ../src/settings.c:72
 msgid "Failed to initialize GConf.  Settings were not saved."
 msgstr ""
 
-#: ../src/maemo-mapper.c:7750 ../src/maemo-mapper.c:8360
+#: ../src/display.c:2561 ../src/main.c:476
 msgid "Failed to open file for reading"
 msgstr ""
 
-#: ../src/maemo-mapper.c:7403 ../src/maemo-mapper.c:7751
+#: ../src/display.c:2562
 msgid "Failed to open file for writing"
 msgstr ""
 
-#: ../src/maemo-mapper.c:3014
+#: ../src/maps.c:652 ../src/maps.c:666
+msgid "Failed to open map database for repository"
+msgstr ""
+
+#: ../src/poi.c:171
 msgid "Failed to open or create database"
 msgstr ""
 
-#: ../src/maemo-mapper.c:1502
+#: ../src/path.c:1553
+msgid "Failed to open path database. Tracks and routes will not be saved."
+msgstr ""
+
+#: ../src/path.c:195 ../src/path.c:221 ../src/path.c:240
+msgid "Failed to write to path database. Tracks and routes may not be saved."
+msgstr ""
+
+#: ../src/main.c:312
+msgid "File"
+msgstr ""
+
+#: ../src/settings.c:1044
+msgid "File Path"
+msgstr ""
+
+#: ../src/gpx.c:479 ../src/gpx.c:806
 msgid "File is incomplete."
 msgstr ""
 
-#: ../src/maemo-mapper.c:2858
+#: ../src/display.c:850
 msgid "Fix"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2867
+#: ../src/display.c:859
 msgid "Fix Quality"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2289
-msgid "Float RTK"
+#: ../src/settings.c:1093
+msgid "Fixed"
 msgstr ""
 
-#: ../src/maemo-mapper.c:13442
-msgid "Format"
+#: ../src/display.c:281
+msgid "Float RTK"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2985
-msgid "Fuel"
+#: ../src/display.c:2444
+msgid "Format"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6189
+#: ../src/menu.c:1564
 msgid "Full Screen"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4747 ../src/maemo-mapper.c:4964
-#: ../src/maemo-mapper.c:6266
+#: ../src/menu.c:1570 ../src/settings.c:778 ../src/settings.c:1004
 msgid "GPS"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2761
+#: ../src/display.c:753
 msgid "GPS Details"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2774
+#: ../src/display.c:766
 msgid "GPS Information"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6258 ../src/maemo-mapper.c:12151
+#: ../src/maps.c:2152 ../src/menu.c:1491
 msgid "GPS Location"
 msgstr ""
 
-#: ../src/maemo-mapper.c:3004
+#: ../src/main.c:311
+msgid "GPSD"
+msgstr ""
+
+#: ../src/settings.c:1025
+msgid "GPSD Host"
+msgstr ""
+
+#: ../src/poi.c:161
 msgid "General landmarks."
 msgstr ""
 
-#: ../src/maemo-mapper.c:3002
+#: ../src/poi.c:159
 msgid "General places of business."
 msgstr ""
 
-#: ../src/maemo-mapper.c:6250
+#: ../src/menu.c:1483 ../src/poi.c:1996
 msgid "Go to"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10900
+#: ../src/menu.c:827
 msgid "Go to Address"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10806
+#: ../src/menu.c:731
 msgid "Go to Lat/Lon"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6483
+#: ../src/cmenu.c:666
 msgid "Go to Nearest"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6460
+#: ../src/cmenu.c:643
 msgid "Go to Next"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4608
+#: ../src/settings.c:644
 msgid "Hardware Keys"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4950
+#: ../src/settings.c:990
 msgid "Hardware Keys..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:2822
+#: ../src/display.c:814
 msgid "Heading"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6291
+#: ../src/menu.c:1595
 msgid "Help..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:2988
+#: ../src/poi.c:145
 msgid "Houses, apartments, or other residences of import."
 msgstr ""
 
-#: ../src/maemo-mapper.c:12937
+#: ../src/poi.c:899
 msgid "ID"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2994
+#: ../src/menu.c:1399
+msgid "Import..."
+msgstr ""
+
+#: ../src/poi.c:151
 msgid "Indoor or Outdoor places to have fun."
 msgstr ""
 
-#: ../src/maemo-mapper.c:5102
-msgid "Information Font Size"
+#: ../src/settings.c:1174
+msgid "Info Font Size"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6151
+#: ../src/menu.c:1383
 msgid "Insert Break"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10493
+#: ../src/menu.c:290
 msgid "Insert Mark"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6153
+#: ../src/menu.c:1385
 msgid "Insert Mark..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:8059
+#: ../src/main.c:268
 msgid "Insert Track Break"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12324
+#: ../src/maps.c:2342
 msgid "Invalid Bottom-Right Latitude"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12331
+#: ../src/maps.c:2349
 msgid "Invalid Bottom-Right Longitude"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10865 ../src/maemo-mapper.c:13267
+#: ../src/menu.c:792 ../src/poi.c:1224
 msgid "Invalid Latitude"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10872 ../src/maemo-mapper.c:13274
+#: ../src/menu.c:799 ../src/poi.c:1231
 msgid "Invalid Longitude"
 msgstr ""
 
-#: ../src/maemo-mapper.c:9534 ../src/maemo-mapper.c:9545
+#: ../src/gps.c:66 ../src/gps.c:77
 msgid "Invalid NMEA input from receiver!"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12310
+#: ../src/maps.c:2328
 msgid "Invalid Top-Left Latitude"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12317
+#: ../src/maps.c:2335
 msgid "Invalid Top-Left Longitude"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10971
+#: ../src/util.c:150
 msgid "Invalid address."
 msgstr ""
 
-#: ../src/maemo-mapper.c:10264
+#: ../src/poi.c:2460
+msgid "Invalid origin or query."
+msgstr ""
+
+#: ../src/path.c:657
 msgid "Invalid source or destination."
 msgstr ""
 
-#: ../src/maemo-mapper.c:6562
+#: ../src/display.c:1077
 msgid ""
 "It looks like this is your first time running Maemo Mapper.  Press OK to "
 "view the the help pages. Otherwise, press Cancel to continue."
 msgstr ""
 
-#: ../src/maemo-mapper.c:5094
-msgid "Keep Display On Only in Fullscreen Mode"
-msgstr ""
-
-#: ../src/maemo-mapper.c:8592 ../src/maemo-mapper.c:12661
-#: ../src/maemo-mapper.c:12950 ../src/maemo-mapper.c:13177
+#: ../src/poi.c:453 ../src/poi.c:615 ../src/poi.c:912 ../src/poi.c:1151
+#: ../src/poi.c:1757
 msgid "Label"
 msgstr ""
 
-#: ../src/maemo-mapper.c:3003
+#: ../src/poi.c:160
 msgid "Landmark"
 msgstr ""
 
-#: ../src/maemo-mapper.c:13161 ../src/maemo-mapper.c:13424
+#: ../src/display.c:2426 ../src/poi.c:1135
 msgid "Lat"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10503 ../src/maemo-mapper.c:13611
+#: ../src/menu.c:300 ../src/path.c:1344
 msgid "Lat, Lon:"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6231
+#: ../src/menu.c:1544
 msgid "Lat/Lon"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6254
+#: ../src/menu.c:1487
 msgid "Lat/Lon..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:2786 ../src/maemo-mapper.c:10816
-#: ../src/maemo-mapper.c:12141 ../src/maemo-mapper.c:13512
+#: ../src/cmenu.c:82 ../src/display.c:778 ../src/maps.c:2142 ../src/menu.c:741
 msgid "Latitude"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6237
+#: ../src/menu.c:1550
 msgid "Lead"
 msgstr ""
 
-#: ../src/maemo-mapper.c:5011
+#: ../src/settings.c:1078
 msgid "Lead Amount"
 msgstr ""
 
-#: ../src/maemo-mapper.c:5082
+#: ../src/main.c:196 ../src/menu.c:1468
+msgid "Left"
+msgstr ""
+
+#: ../src/settings.c:1151
 msgid "Line Width"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2831
+#: ../src/display.c:823
 msgid "Local time"
 msgstr ""
 
-#: ../src/maemo-mapper.c:5162 ../src/maemo-mapper.c:6409
-#: ../src/maemo-mapper.c:8587
+#: ../src/cmenu.c:592 ../src/poi.c:448 ../src/settings.c:1249
 msgid "Location"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2997
+#: ../src/poi.c:154
 msgid "Lodging"
 msgstr ""
 
-#: ../src/maemo-mapper.c:13169 ../src/maemo-mapper.c:13433
+#: ../src/display.c:2435 ../src/poi.c:1143
 msgid "Lon"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2795 ../src/maemo-mapper.c:10829
-#: ../src/maemo-mapper.c:12145 ../src/maemo-mapper.c:13513
+#: ../src/cmenu.c:83 ../src/display.c:787 ../src/maps.c:2146 ../src/menu.c:755
 msgid "Longitude"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4484 ../src/maemo-mapper.c:4968
+#: ../src/settings.c:531
 msgid "MAC"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11470
+#: ../src/settings.c:1009
+msgid "MAC Address"
+msgstr ""
+
+#: ../src/maps.c:1498
 msgid ""
 "Maemo Mapper will now download and add a list of possibly-duplicate "
 "repositories from the internet.  Continue?"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12033
+#: ../src/maps.c:2034
 msgid "Manage Maps"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6168
+#: ../src/menu.c:1415
 msgid "Manage Maps..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:11550
+#: ../src/maps.c:1578
 msgid "Manage Repositories"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6170
+#: ../src/menu.c:1417
 msgid "Manage Repositories..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:2291
+#: ../src/display.c:283
 msgid "Manual"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6163
+#: ../src/menu.c:1410
 msgid "Maps"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2876
+#: ../src/display.c:868
 msgid "Max speed"
 msgstr ""
 
-#: ../src/maemo-mapper.c:5078
+#: ../src/settings.c:1147
 msgid "Misc."
 msgstr ""
 
-#: ../src/maemo-mapper.c:5114
+#: ../src/settings.c:1204
 msgid "Misc. 2"
 msgstr ""
 
-#: ../src/maemo-mapper.c:3006
+#: ../src/poi.c:163
 msgid "Miscellaneous category for everything else."
 msgstr ""
 
-#: ../src/maemo-mapper.c:12285 ../src/maemo-mapper.c:12449
+#: ../src/maps.c:2294 ../src/menu.c:520
 msgid ""
 "NOTE: You must set a Map URI in the current repository in order to download "
 "maps."
 msgstr ""
 
-#: ../src/maemo-mapper.c:11171 ../src/maemo-mapper.c:11409
+#: ../src/maps.c:1197 ../src/maps.c:1437
 msgid "Name"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6262
+#: ../src/menu.c:1495
 msgid "Nearest POI"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11161
+#: ../src/maps.c:1187
 msgid "New Name"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11399
+#: ../src/maps.c:1427
 msgid "New Repository"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11589
+#: ../src/maps.c:1617
 msgid "New..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:6260
+#: ../src/menu.c:1493
 msgid "Next Waypoint"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11362
+#: ../src/maps.c:1390
 msgid "Next-able"
 msgstr ""
 
-#: ../src/maemo-mapper.c:5283
+#: ../src/settings.c:1472
 msgid ""
-"No GPS Receiver MAC provided.\n"
+"No GPS Receiver provided.\n"
 "GPS will be disabled."
 msgstr ""
 
-#: ../src/maemo-mapper.c:8530 ../src/maemo-mapper.c:11082
+#: ../src/menu.c:950 ../src/poi.c:391 ../src/poi.c:2772
 msgid "No POIs found."
 msgstr ""
 
-#: ../src/maemo-mapper.c:6243
+#: ../src/poi.c:1401
+msgid "No POIs were found."
+msgstr ""
+
+#: ../src/main.c:309 ../src/menu.c:1556
 msgid "None"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4984
-msgid ""
-"Note: You can enter a device path\n"
-"(e.g. \"/dev/rfcomm0\")."
+#: ../src/menu.c:1473
+msgid "North"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6127 ../src/maemo-mapper.c:6147
+#: ../src/menu.c:1359 ../src/menu.c:1379
 msgid "Open..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:6572
+#: ../src/display.c:1087
 msgid ""
 "OpenStreetMap.org provides public, free-to-use maps.  You can also download "
 "a sample set of repositories from  the internet by using the \"Download...\" "
 "button."
 msgstr ""
 
-#: ../src/maemo-mapper.c:10083
+#: ../src/path.c:1126 ../src/poi.c:2268 ../src/poi.c:2565
 msgid "Origin"
 msgstr ""
 
-#: ../src/maemo-mapper.c:3005
+#: ../src/poi.c:162
 msgid "Other"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12075
+#: ../src/maps.c:2076
 msgid "Overwrite"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4792 ../src/maemo-mapper.c:5177
-#: ../src/maemo-mapper.c:6464
+#: ../src/cmenu.c:647 ../src/menu.c:1395 ../src/menu.c:1534
+#: ../src/settings.c:823 ../src/settings.c:1264
 msgid "POI"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12903
+#: ../src/poi.c:865
 msgid "POI Categories"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6222
-msgid "POI Categories..."
+#: ../src/poi.c:1987
+msgid "POI List"
 msgstr ""
 
-#: ../src/maemo-mapper.c:5181
+#: ../src/settings.c:1268
 msgid "POI database"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6218
-msgid "POIs"
+#: ../src/poi.c:1907
+msgid "POIs Exported"
+msgstr ""
+
+#: ../src/poi.c:1395
+msgid ""
+"POIs were added to the POI database.  The following screen will allow you to "
+"modify or delete any of the new POIs."
 msgstr ""
 
-#: ../src/maemo-mapper.c:2287
+#: ../src/display.c:279
 msgid "PPS"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8044
+#: ../src/poi.c:2252
+msgid "Page"
+msgstr ""
+
+#: ../src/menu.c:1460
+msgid "Pan"
+msgstr ""
+
+#: ../src/main.c:245
 msgid "Pan East"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8041
+#: ../src/main.c:242
 msgid "Pan North"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8043
-msgid "Pan South"
+#: ../src/settings.c:1065
+msgid "Pan Sensitivity"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8042
-msgid "Pan West"
+#: ../src/main.c:244
+msgid "Pan South"
 msgstr ""
 
-#  This word refers to Pitch as in of a person's voice.
-#: ../src/maemo-mapper.c:5067
-msgid "Pitch"
+#: ../src/main.c:243
+msgid "Pan West"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2990
+#: ../src/poi.c:147
 msgid "Places to eat or drink."
 msgstr ""
 
-#: ../src/maemo-mapper.c:2992
+#: ../src/poi.c:149
 msgid "Places to shop or acquire services."
 msgstr ""
 
-#: ../src/maemo-mapper.c:2998
+#: ../src/poi.c:155
 msgid "Places to stay temporarily or for the night."
 msgstr ""
 
-#: ../src/maemo-mapper.c:10567
+#: ../src/menu.c:364
 msgid "Please provide a description for the mark."
 msgstr ""
 
-#: ../src/maemo-mapper.c:4519
+#: ../src/settings.c:566
 msgid "Please select a bluetooth device from the list."
 msgstr ""
 
-#: ../src/maemo-mapper.c:13289
-msgid "Please specify a category for the POI."
+#: ../src/poi.c:1250 ../src/poi.c:1532
+msgid "Please specify a category."
 msgstr ""
 
-#: ../src/maemo-mapper.c:13282
-msgid "Please specify a name for the POI."
+#: ../src/poi.c:2104 ../src/poi.c:2425
+msgid "Please specify a default category."
 msgstr ""
 
-#: ../src/maemo-mapper.c:12719
+#: ../src/poi.c:673
 msgid "Please specify a name for the category."
 msgstr ""
 
-#: ../src/maemo-mapper.c:10173
-msgid "Please specify a source URL."
+#: ../src/poi.c:1243
+msgid "Please specify a name."
 msgstr ""
 
-#: ../src/maemo-mapper.c:10217
-msgid "Please specify a start location."
+#: ../src/poi.c:2432
+msgid "Please specify a query."
 msgstr ""
 
-#: ../src/maemo-mapper.c:10941
-msgid "Please specify an address."
-msgstr ""
-
-#: ../src/maemo-mapper.c:10224
-msgid "Please specify an end location."
-msgstr ""
-
-#: ../src/maemo-mapper.c:13340
-msgid "Problem adding POI"
+#: ../src/path.c:1214 ../src/poi.c:2368
+msgid "Please specify a source URL."
 msgstr ""
 
-#: ../src/maemo-mapper.c:12756
-msgid "Problem adding category"
+#: ../src/path.c:1256
+msgid "Please specify a start location."
 msgstr ""
 
-#: ../src/maemo-mapper.c:12567 ../src/maemo-mapper.c:13019
-msgid "Problem deleting POI"
+#: ../src/path.c:1263
+msgid "Please specify an end location."
 msgstr ""
 
-#: ../src/maemo-mapper.c:12576
-msgid "Problem deleting category"
+#: ../src/poi.c:2419 ../src/poi.c:2696
+msgid "Please specify an origin."
 msgstr ""
 
-#: ../src/maemo-mapper.c:12795
-msgid "Problem updating Category"
+#: ../src/settings.c:1110
+msgid "Points"
 msgstr ""
 
-#: ../src/maemo-mapper.c:13318
-msgid "Problem updating POI"
+#: ../src/settings.c:1035
+msgid "Port"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12741
-msgid "Problem updating category"
+#: ../src/maps.c:850
+msgid "Processing Maps"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2946
-msgid "Problem with POI database"
+#: ../src/poi.c:2278 ../src/poi.c:2575
+msgid "Query"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2288
+#: ../src/display.c:280
 msgid "Real Time Kinematic"
 msgstr ""
 
-#: ../src/maemo-mapper.c:3723
+#: ../src/path.c:919
 msgid "Really clear the track?"
 msgstr ""
 
-#: ../src/maemo-mapper.c:3678
+#: ../src/path.c:798
 msgid "Recalculating directions..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:2993
+#: ../src/poi.c:150
 msgid "Recreation"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11583
+#: ../src/maps.c:1611
 msgid "Rename..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:11440
+#: ../src/maps.c:1468
 msgid "Replace all repositories with the default repository?"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6137
+#: ../src/menu.c:1369 ../src/menu.c:1452
 msgid "Reset"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6281 ../src/maemo-mapper.c:8069
+#: ../src/main.c:278 ../src/menu.c:1585
 msgid "Reset Bluetooth"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4699
+#: ../src/main.c:247
+msgid "Reset Viewing Angle"
+msgstr ""
+
+#: ../src/settings.c:730
 msgid "Reset all colors to their original defaults?"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4580
+#: ../src/settings.c:616
 msgid "Reset all hardware keys to their original defaults?"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4614 ../src/maemo-mapper.c:4735
-#: ../src/maemo-mapper.c:11561
+#: ../src/maps.c:1589 ../src/settings.c:650 ../src/settings.c:766
 msgid "Reset..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:2987
+#: ../src/poi.c:144
 msgid "Residence"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4777 ../src/maemo-mapper.c:6123
-#: ../src/maemo-mapper.c:6204
+#: ../src/poi.c:146
+msgid "Restaurant"
+msgstr ""
+
+#: ../src/main.c:194 ../src/menu.c:1470
+msgid "Right"
+msgstr ""
+
+#: ../src/menu.c:1444
+msgid "Rotate"
+msgstr ""
+
+#: ../src/settings.c:1097
+msgid "Rotate Sensit."
+msgstr ""
+
+#: ../src/main.c:249
+msgid "Rotate View Clockwise"
+msgstr ""
+
+#: ../src/main.c:251
+msgid "Rotate View Counter-Clockwise"
+msgstr ""
+
+#: ../src/menu.c:1355 ../src/menu.c:1520 ../src/settings.c:808
 msgid "Route"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10311
+#: ../src/path.c:672
 msgid "Route Downloaded"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8368 ../src/maemo-mapper.c:10360
+#: ../src/main.c:485 ../src/menu.c:119
 msgid "Route Opened"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10615
+#: ../src/menu.c:150
 msgid "Route Saved"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10705
+#: ../src/menu.c:1048
 msgid "Routes are now hidden"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10699
+#: ../src/menu.c:1042
 msgid "Routes are now shown"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2285
+#: ../src/display.c:277
 msgid "SPS"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2849
+#: ../src/display.c:841
 msgid "Sat in use"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2840
+#: ../src/display.c:832
 msgid "Sat in view"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2781
+#: ../src/display.c:773
 msgid "Satellites details"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2707
+#: ../src/display.c:699
 msgid "Satellites in view"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6131 ../src/maemo-mapper.c:6149
+#: ../src/menu.c:1363 ../src/menu.c:1381
 msgid "Save..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:6199
+#: ../src/menu.c:1510
 msgid "Scale"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4978
+#: ../src/settings.c:1019
 msgid "Scan..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:4495
+#: ../src/settings.c:542
 msgid "Scanning for Bluetooth Devices"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2999
+#: ../src/poi.c:156
 msgid "School"
 msgstr ""
 
-#: ../src/maemo-mapper.c:3138
+#: ../src/gps.c:790
 msgid "Searching for GPS receiver"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4459
+#: ../src/settings.c:506
 msgid "Select Bluetooth Device"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8054
+#: ../src/main.c:263
 msgid "Select Next Repository"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8560
+#: ../src/poi.c:421
 msgid "Select POI"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8630
+#: ../src/poi.c:1933
+msgid ""
+"Select an operation to perform\n"
+"on the POIs that you checked\n"
+"in the POI list."
+msgstr ""
+
+#: ../src/poi.c:486
 msgid "Select one POI from the list."
 msgstr ""
 
-#: ../src/maemo-mapper.c:4998
-msgid "Sensitivity"
+#: ../src/poi.c:142
+msgid "Service Station"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6431
+#: ../src/poi.c:1502 ../src/poi.c:1939
+msgid "Set Category..."
+msgstr ""
+
+#: ../src/cmenu.c:614
 msgid "Set as GPS Location"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4940
+#: ../src/settings.c:980
 msgid "Settings"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6288
+#: ../src/menu.c:1592
 msgid "Settings..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:12058
+#: ../src/maps.c:2059
 msgid "Setup"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2991
+#: ../src/poi.c:148
 msgid "Shopping/Services"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6442
+#: ../src/menu.c:1501
+msgid "Show"
+msgstr ""
+
+#: ../src/cmenu.c:625
 msgid "Show Description"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6157 ../src/maemo-mapper.c:8064
+#: ../src/main.c:273 ../src/menu.c:1389
 msgid "Show Distance from Beginning"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8062
+#: ../src/main.c:271
 msgid "Show Distance from Last Break"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6155
+#: ../src/menu.c:1387
 msgid "Show Distance from Last Mark"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6418 ../src/maemo-mapper.c:6449
-#: ../src/maemo-mapper.c:6473
+#: ../src/cmenu.c:601 ../src/cmenu.c:632 ../src/cmenu.c:656
 msgid "Show Distance to"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6135 ../src/maemo-mapper.c:8058
+#: ../src/main.c:267 ../src/menu.c:1367
 msgid "Show Distance to End of Route"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6133 ../src/maemo-mapper.c:8056
+#: ../src/main.c:265 ../src/menu.c:1365
 msgid "Show Distance to Next Waypoint"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6274
+#: ../src/menu.c:1578
 msgid "Show Information"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6415 ../src/maemo-mapper.c:6440
+#: ../src/cmenu.c:598 ../src/cmenu.c:623
 msgid "Show Lat/Lon"
 msgstr ""
 
-#: ../src/maemo-mapper.c:5196
+#: ../src/settings.c:1283
 msgid "Show POI below zoom"
 msgstr ""
 
-#: ../src/maemo-mapper.c:13414
+#: ../src/display.c:2416
 msgid "Show Position"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2292
+#: ../src/display.c:284
 msgid "Simulation"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10049
+#: ../src/path.c:1086 ../src/poi.c:2220
 msgid "Source URL"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2804 ../src/maemo-mapper.c:5055
+#: ../src/menu.c:1475
+msgid "South"
+msgstr ""
+
+#: ../src/display.c:796
 msgid "Speed"
 msgstr ""
 
-#: ../src/maemo-mapper.c:5152
+#: ../src/settings.c:1239
 msgid "Speed Limit"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2986
+#: ../src/poi.c:143
 msgid "Stations for purchasing fuel for vehicles."
 msgstr ""
 
-#: ../src/maemo-mapper.c:3399
+#: ../src/maps.c:504
+msgid ""
+"The current repository is in a legacy format and will be converted.  You "
+"should delete your old maps if you no longer plan to use them."
+msgstr ""
+
+#: ../src/path.c:551
 msgid "The current route is empty."
 msgstr ""
 
-#: ../src/maemo-mapper.c:3445 ../src/maemo-mapper.c:3460
+#: ../src/path.c:597 ../src/path.c:612
 msgid "The current track is empty."
 msgstr ""
 
-#: ../src/maemo-mapper.c:4660
+#: ../src/settings.c:696
 msgid "The following action is mapped to multiple keys"
 msgstr ""
 
-#: ../src/maemo-mapper.c:9002
+#: ../src/input.c:364
 msgid "There are no other next-able repositories."
 msgstr ""
 
-#: ../src/maemo-mapper.c:13853
+#: ../src/cmenu.c:265 ../src/cmenu.c:287 ../src/cmenu.c:306 ../src/cmenu.c:326
+#: ../src/cmenu.c:345 ../src/cmenu.c:364 ../src/cmenu.c:442 ../src/cmenu.c:461
 msgid "There are no waypoints."
 msgstr ""
 
-#: ../src/maemo-mapper.c:3380 ../src/maemo-mapper.c:11044
+#: ../src/menu.c:912 ../src/path.c:532
 msgid "There is no next waypoint."
 msgstr ""
 
-#: ../src/maemo-mapper.c:8046
+#: ../src/main.c:253
 msgid "Toggle Auto-Center"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8048
+#: ../src/main.c:255
+msgid "Toggle Auto-Rotate"
+msgstr ""
+
+#: ../src/main.c:257
 msgid "Toggle Fullscreen"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8065
+#: ../src/main.c:274
 msgid "Toggle GPS"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8066
+#: ../src/main.c:275
 msgid "Toggle GPS Info"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8053
+#: ../src/main.c:262
 msgid "Toggle POIs"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8052
+#: ../src/main.c:261
 msgid "Toggle Scale"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8068
+#: ../src/main.c:277
 msgid "Toggle Speed Limit"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8051
+#: ../src/main.c:260
 msgid "Toggle Tracks"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8095 ../src/maemo-mapper.c:12186
+#: ../src/main.c:304 ../src/maps.c:2187
 msgid "Top-Left"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8096
+#: ../src/main.c:305
 msgid "Top-Right"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4762 ../src/maemo-mapper.c:6143
-#: ../src/maemo-mapper.c:6209
+#: ../src/menu.c:1375 ../src/menu.c:1525 ../src/settings.c:793
 msgid "Track"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10434
+#: ../src/menu.c:231
 msgid "Track Opened"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10456
+#: ../src/menu.c:253
 msgid "Track Saved"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10655
+#: ../src/menu.c:985
 msgid "Tracks are now hidden"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10649
+#: ../src/menu.c:979
 msgid "Tracks are now shown"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2995
+#: ../src/poi.c:152
 msgid "Transportation"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11278
+#: ../src/maps.c:1304
 msgid "URL Format"
 msgstr ""
 
-#: ../src/maemo-mapper.c:5543
-msgid "Unable to create cache directory for repository"
+#: ../src/maps.c:684
+msgid "Unable to create map database for repository"
+msgstr ""
+
+#: ../src/settings.c:1162
+msgid "Unblank Screen"
 msgstr ""
 
-#: ../src/maemo-mapper.c:5118
+#: ../src/settings.c:1191
 msgid "Units"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11003
+#: ../src/util.c:155
 msgid "Unknown error while locating address."
 msgstr ""
 
-#: ../src/maemo-mapper.c:10070
+#: ../src/main.c:193 ../src/menu.c:1464
+msgid "Up"
+msgstr ""
+
+#: ../src/path.c:1103 ../src/poi.c:2233 ../src/poi.c:2531
 msgid "Use End of Route"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10060
+#: ../src/path.c:1097 ../src/poi.c:2227 ../src/poi.c:2525
 msgid "Use GPS Location"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6214
+#: ../src/menu.c:1530
 msgid "Velocity Vector"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6181
+#: ../src/menu.c:1428
 msgid "View"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12167
+#: ../src/maps.c:2168
 msgid "View Center"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11333
+#: ../src/maps.c:1361
 msgid "View Zoom Steps"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6470
+#: ../src/cmenu.c:653
 msgid "View/Edit..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:12554
+#: ../src/poi.c:508
 msgid "WARNING: All POIs in that category will also be deleted!"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6435
+#: ../src/cmenu.c:618
 msgid "Waypoint"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6579
+#: ../src/menu.c:1477
+msgid "West"
+msgstr ""
+
+#: ../src/display.c:1094
 msgid ""
 "You will now see a blank screen.  You can download maps using the \"Manage "
 "Maps\" menu item in the \"Maps\" menu.  Or, press OK to enable Auto-Download."
 msgstr ""
 
-#: ../src/maemo-mapper.c:12115
+#: ../src/maps.c:2116 ../src/menu.c:1434
 msgid "Zoom"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6185 ../src/maemo-mapper.c:8049
+#: ../src/main.c:258 ../src/menu.c:1438
 msgid "Zoom In"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6194
+#: ../src/menu.c:1505
 msgid "Zoom Level"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12121
+#: ../src/maps.c:2122
 msgid "Zoom Levels to Download: (0 = most detail)"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6187 ../src/maemo-mapper.c:8050
+#: ../src/main.c:259 ../src/menu.c:1440
 msgid "Zoom Out"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8815 ../src/maemo-mapper.c:8928
-#: ../src/maemo-mapper.c:12356 ../src/maemo-mapper.c:12374
+#: ../src/input.c:103 ../src/input.c:290 ../src/menu.c:546 ../src/menu.c:564
 msgid "Zoom to Level"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11890 ../src/maemo-mapper.c:11897
+#: ../src/maps.c:1880 ../src/maps.c:1887
 msgid "about"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2708
+#: ../src/display.c:700
 msgid "in use"
 msgstr ""
 
-#: ../src/maemo-mapper.c:7999
+#: ../src/main.c:189
 msgid "km"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11810 ../src/maemo-mapper.c:11898
+#: ../src/maps.c:1791 ../src/maps.c:1888
 msgid "maps"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11804 ../src/maemo-mapper.c:11891
+#: ../src/maps.c:1785 ../src/maps.c:1881
 msgid "maps "
 msgstr ""
 
-#: ../src/maemo-mapper.c:8000
+#: ../src/display.c:1466
+msgid "maps failed to download."
+msgstr ""
+
+#: ../src/main.c:190
 msgid "mi."
 msgstr ""
 
-#: ../src/maemo-mapper.c:8001
+#: ../src/main.c:191
 msgid "n.m."
 msgstr ""
 
-#: ../src/maemo-mapper.c:2862
+#: ../src/display.c:854
 msgid "nofix"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2293 ../src/maemo-mapper.c:2871
+#: ../src/display.c:285 ../src/display.c:863
 msgid "none"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11810 ../src/maemo-mapper.c:11898
+#: ../src/maps.c:1791 ../src/maps.c:1888
 msgid "up to about"
 msgstr ""
index ee3794c2f92e719f470202b6d86e09ac791155c7..176ce26f98c40ab7d68491cbad0efc5fb1b5ad5c 100644 (file)
@@ -13,7 +13,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: es_ES\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-07-07 20:45-0400\n"
+"POT-Creation-Date: 2007-11-01 15:35-0400\n"
 "PO-Revision-Date: 2007-06-17 05:52+0200\n"
 "Last-Translator: Jaime Crespo <devel@jynus.com>\n"
 "Language-Team: \n"
@@ -23,72 +23,73 @@ msgstr ""
 "X-Generator: KBabel 1.11.4\n"
 "Plural-Forms:  nplurals=2; plural=(n != 1);\n"
 
-#: ../src/maemo-mapper.c:12960
+#: ../src/poi.c:922
 msgid "# POIs"
 msgstr "nº de puntos de interés"
 
-#: ../src/maemo-mapper.c:6293
+#: ../src/menu.c:1597
 msgid "About..."
 msgstr "Acerca de..."
 
-#: ../src/maemo-mapper.c:12916
-msgid "Add"
-msgstr "Añadir"
-
-#: ../src/maemo-mapper.c:12650
+#: ../src/poi.c:604
 msgid "Add Category"
 msgstr "Añadir categoría"
 
-#: ../src/maemo-mapper.c:13149
+#: ../src/poi.c:1123
 msgid "Add POI"
 msgstr "Añadir punto de interés"
 
-#: ../src/maemo-mapper.c:6427 ../src/maemo-mapper.c:6456
+#: ../src/cmenu.c:610 ../src/cmenu.c:639
 msgid "Add POI..."
 msgstr "Añadir punto de interés..."
 
-#: ../src/maemo-mapper.c:6423 ../src/maemo-mapper.c:6478
+#: ../src/cmenu.c:606 ../src/cmenu.c:661
 msgid "Add Route Point"
 msgstr "Añadir punto en itinerario"
 
-#: ../src/maemo-mapper.c:13601
+#: ../src/path.c:1334
 msgid "Add Waypoint"
 msgstr "Añadir etapa"
 
-#: ../src/maemo-mapper.c:6425 ../src/maemo-mapper.c:6480
+#: ../src/cmenu.c:608 ../src/cmenu.c:663
 msgid "Add Waypoint..."
 msgstr "Añadir etapa..."
 
-#: ../src/maemo-mapper.c:10910
+#: ../src/poi.c:878
+#, fuzzy
+msgid "Add..."
+msgstr "Añadir punto de interés..."
+
+#: ../src/menu.c:837
 msgid "Address"
 msgstr "Dirección"
 
-#: ../src/maemo-mapper.c:10987
+#: ../src/menu.c:862
 msgid "Address Located"
 msgstr "Dirección localizada"
 
-#: ../src/maemo-mapper.c:6256
+#: ../src/menu.c:1489
 msgid "Address..."
 msgstr "Dirección..."
 
-#: ../src/maemo-mapper.c:5029
+#: ../src/settings.c:1126
 msgid "Advance Notice"
 msgstr "Notificación previa"
 
-#: ../src/maemo-mapper.c:12100
+#: ../src/maps.c:2101
 msgid "Along Route - Radius (tiles):"
 msgstr "Por un itinerario - Radio (en cuadrículas):"
 
-#: ../src/maemo-mapper.c:2813
+#: ../src/display.c:805
 msgid "Altitude"
 msgstr "Altitud"
 
-#: ../src/maemo-mapper.c:4501
+#: ../src/settings.c:548
 msgid "An error occurred while attempting to scan for bluetooth devices."
 msgstr ""
 "Ha ocurrido un error mientras se intentaba buscar dispositivos bluetooth."
 
-#: ../src/maemo-mapper.c:11489
+#: ../src/maps.c:1517
 msgid ""
 "An error occurred while retrieving the repositories.  The web service may be "
 "temporarily down."
@@ -96,7 +97,7 @@ msgstr ""
 "Ha ocurrido un error al obtener los repositorios. El servicio web podría "
 "estar temporalmente no disponible."
 
-#: ../src/maemo-mapper.c:8829
+#: ../src/gps.c:955
 msgid ""
 "An error occurred while trying to reset the bluetooth radio.\n"
 "\n"
@@ -108,146 +109,205 @@ msgstr ""
 "\n"
 "¿Está seguro de haber modificado el archivo /etc/sudoers?"
 
-#: ../src/maemo-mapper.c:5025
+#: ../src/settings.c:1122
 msgid "Announce"
 msgstr "Notif."
 
-#: ../src/maemo-mapper.c:12137
+#: ../src/maps.c:2138
 msgid "Area"
 msgstr "Área"
 
-#: ../src/maemo-mapper.c:4994 ../src/maemo-mapper.c:6227
+#: ../src/menu.c:1540 ../src/settings.c:1061
 msgid "Auto-Center"
 msgstr "Autocentrar"
 
-#: ../src/maemo-mapper.c:10774
+#: ../src/menu.c:1114
 msgid "Auto-Center Mode: Lat/Lon"
 msgstr "Modo de autocentrado: Lat/Lon"
 
-#: ../src/maemo-mapper.c:10759
+#: ../src/menu.c:1097
 msgid "Auto-Center Mode: Lead"
 msgstr "Modo de autocentrado: Frente"
 
-#: ../src/maemo-mapper.c:10788
+#: ../src/menu.c:1130
 msgid "Auto-Center Off"
 msgstr "Desactivar autocentrado"
 
-#: ../src/maemo-mapper.c:6172
+#: ../src/menu.c:1419
 msgid "Auto-Download"
 msgstr "Descarga automática"
 
-#: ../src/maemo-mapper.c:10064
+#: ../src/settings.c:1221
+#, fuzzy
+msgid "Auto-Download Pre-cache"
+msgstr "Descarga automática"
+
+#: ../src/menu.c:1454
+#, fuzzy
+msgid "Auto-Rotate"
+msgstr "Actualizar automáticamente"
+
+#: ../src/menu.c:624
+msgid "Auto-Rotate Disabled"
+msgstr ""
+
+#: ../src/menu.c:619
+msgid "Auto-Rotate Enabled"
+msgstr ""
+
+#: ../src/path.c:1113
 msgid "Auto-Update"
 msgstr "Actualizar automáticamente"
 
-#: ../src/maemo-mapper.c:10076
+#: ../src/path.c:1119
 msgid "Avoid Highways"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8098
+#: ../src/poi.c:1749
+#, fuzzy
+msgid "Bear."
+msgstr "Borrar"
+
+#: ../src/main.c:310
+#, fuzzy
+msgid "Bluetooth"
+msgstr "Reiniciar Bluetooth"
+
+#: ../src/main.c:307
 msgid "Bottom-Left"
 msgstr "Inferior izquierda"
 
-#: ../src/maemo-mapper.c:8097 ../src/maemo-mapper.c:12208
+#: ../src/main.c:306 ../src/maps.c:2209
 msgid "Bottom-Right"
 msgstr "Inferior derecha"
 
-#: ../src/maemo-mapper.c:3767
+#: ../src/path.c:967
 msgid "Break already inserted."
 msgstr "Ya se ha insertado una parada."
 
-#: ../src/maemo-mapper.c:5191 ../src/maemo-mapper.c:11297
+#: ../src/poi.c:2509
+#, fuzzy
+msgid "Browse POIs"
+msgstr "Activar/desactivar puntos de interés"
+
+#: ../src/maps.c:1323 ../src/menu.c:1403 ../src/settings.c:1054
+#: ../src/settings.c:1278
 msgid "Browse..."
 msgstr "Navegar..."
 
-#: ../src/maemo-mapper.c:2996
+#: ../src/poi.c:153
 msgid "Bus stops, airports, train stations, etc."
 msgstr "Paradas de autobús, aeropuertos, estaciones de tren, etc."
 
-#: ../src/maemo-mapper.c:3001
+#: ../src/poi.c:158
 msgid "Business"
 msgstr "Negocios"
 
-#: ../src/maemo-mapper.c:12091
+#: ../src/maps.c:2092
 msgid "By Area (see tab)"
 msgstr "Por área (ver pestaña)"
 
-#: ../src/maemo-mapper.c:11287
-msgid "Cache Dir."
+#: ../src/maps.c:1313
+#, fuzzy
+msgid "Cache DB"
 msgstr "Directorio de caché."
 
-#: ../src/maemo-mapper.c:11227
+#: ../src/maps.c:1253
 msgid ""
 "Cannot delete the last repository - there must be at lease one repository."
 msgstr ""
 "No se puede borrar el último repositorio - debe haber al menos un "
 "repositorio."
 
-#: ../src/maemo-mapper.c:12416
+#: ../src/menu.c:1177
+#, fuzzy
 msgid ""
-"Cannot enable GPS until a GPS Receiver MAC is set in the Settings dialog box."
+"Cannot enable GPS until a GPS receiver is set up in the Settings dialog box."
 msgstr ""
 "No se puede activar el GPS hasta que se introduzca la MAC del receptor GPS "
 "en el cuadro de diálogo de preferencias."
 
-#: ../src/maemo-mapper.c:8597 ../src/maemo-mapper.c:13185
+#: ../src/menu.c:1405
+#, fuzzy
+msgid "Categories..."
+msgstr "Categorías de puntos de interés..."
+
+#: ../src/poi.c:458 ../src/poi.c:1159 ../src/poi.c:1512 ../src/poi.c:1732
+#: ../src/poi.c:2089 ../src/poi.c:2243 ../src/poi.c:2540
 msgid "Category"
 msgstr "Categoría"
 
-#: ../src/maemo-mapper.c:6139 ../src/maemo-mapper.c:6159
-#: ../src/maemo-mapper.c:12044
+#: ../src/poi.c:1928 ../src/poi.c:2003
+msgid "Checked POI Actions..."
+msgstr ""
+
+#: ../src/maps.c:2045 ../src/menu.c:1371 ../src/menu.c:1391
 msgid "Clear"
 msgstr "Borrar"
 
-#: ../src/maemo-mapper.c:8060
+#: ../src/main.c:269
 msgid "Clear Track"
 msgstr "Borrar traza"
 
-#: ../src/maemo-mapper.c:6295
+#: ../src/menu.c:1448
+#, fuzzy
+msgid "Clockwise"
+msgstr "Cerrar"
+
+#: ../src/menu.c:1599
 msgid "Close"
 msgstr "Cerrar"
 
-#: ../src/maemo-mapper.c:4729
+#: ../src/settings.c:760
 msgid "Colors"
 msgstr "Colores"
 
-#: ../src/maemo-mapper.c:4953
+#: ../src/settings.c:993
 msgid "Colors..."
 msgstr "Colores..."
 
-#: ../src/maemo-mapper.c:11803 ../src/maemo-mapper.c:11890
+#: ../src/menu.c:1515
+msgid "Compass Rose"
+msgstr ""
+
+#: ../src/maps.c:1784 ../src/maps.c:1880
 msgid "Confirm DELETION of"
 msgstr "Confirmar el BORRADO de"
 
-#: ../src/maemo-mapper.c:11234
+#: ../src/maps.c:1260
 msgid "Confirm delete of repository"
 msgstr "Confirmar el borrado del repositorio"
 
-#: ../src/maemo-mapper.c:13966
+#: ../src/cmenu.c:385
 msgid "Confirm delete of waypoint"
 msgstr "Confirmar el borrado de la etapa"
 
-#: ../src/maemo-mapper.c:11809 ../src/maemo-mapper.c:11896
+#: ../src/maps.c:1790 ../src/maps.c:1886
 msgid "Confirm download of"
 msgstr "Confirmar la descarga de"
 
-#: ../src/maemo-mapper.c:4663
+#: ../src/settings.c:699
 msgid "Continue?"
 msgstr "¿Desea continuar?"
 
-#: ../src/maemo-mapper.c:13451
+#: ../src/display.c:2453
 msgid "Copy"
 msgstr "Copiar"
 
-#: ../src/maemo-mapper.c:6446
+#: ../src/cmenu.c:629
 msgid "Copy Description"
 msgstr "Copiar descripción"
 
-#: ../src/maemo-mapper.c:6444
+#: ../src/cmenu.c:627
 msgid "Copy Lat/Lon"
 msgstr "Copiar Lat/Lon"
 
-#: ../src/maemo-mapper.c:13684
+#: ../src/menu.c:1450
+#, fuzzy
+msgid "Counter"
+msgstr "Itinerario"
+
+#: ../src/path.c:1417
 msgid ""
 "Creating a \"waypoint\" with no description actually adds a break point.  Is "
 "that what you want?"
@@ -255,335 +315,451 @@ msgstr ""
 "Crear una \"etapa\" sin descripción hace que se añada una parada. ¿Es eso lo "
 "que desea?"
 
-#: ../src/maemo-mapper.c:2286
+#: ../src/display.c:278
 msgid "DGPS"
 msgstr "DGPS"
 
-#: ../src/maemo-mapper.c:5129
+#: ../src/poi.c:2079
+#, fuzzy
+msgid "Default Category"
+msgstr "¿Desea eliminar la categoría?"
+
+#: ../src/settings.c:1208
 msgid "Degrees Format"
 msgstr "Formato de grados"
 
-#: ../src/maemo-mapper.c:12631 ../src/maemo-mapper.c:13124
-msgid "Delete"
-msgstr "Eliminar"
-
-#: ../src/maemo-mapper.c:12081
+#: ../src/maps.c:2082
 msgid "Delete Maps"
 msgstr "Eliminar mapas"
 
-#: ../src/maemo-mapper.c:13008
+#: ../src/poi.c:958
 msgid "Delete POI?"
 msgstr "¿Desea eliminar el punto de interés?"
 
-#: ../src/maemo-mapper.c:12552
+#: ../src/poi.c:506
 msgid "Delete category?"
 msgstr "¿Desea eliminar la categoría?"
 
-#: ../src/maemo-mapper.c:6453 ../src/maemo-mapper.c:11586
+#: ../src/poi.c:1843
+#, fuzzy
+msgid "Delete selected POI?"
+msgstr "¿Desea eliminar el punto de interés?"
+
+#: ../src/cmenu.c:636 ../src/maps.c:1614 ../src/poi.c:585 ../src/poi.c:1096
+#: ../src/poi.c:1943
 msgid "Delete..."
 msgstr "Eliminar..."
 
-#: ../src/maemo-mapper.c:4489 ../src/maemo-mapper.c:10513
-#: ../src/maemo-mapper.c:12669 ../src/maemo-mapper.c:12955
-#: ../src/maemo-mapper.c:13212 ../src/maemo-mapper.c:13626
+#: ../src/menu.c:310 ../src/path.c:1359 ../src/poi.c:623 ../src/poi.c:917
+#: ../src/poi.c:1174 ../src/settings.c:536
 msgid "Description"
 msgstr "Descripción"
 
-#: ../src/maemo-mapper.c:10093
+#: ../src/path.c:1136
 msgid "Destination"
 msgstr "Destino"
 
-#: ../src/maemo-mapper.c:6278
+#: ../src/menu.c:1582
 msgid "Details..."
 msgstr "Detalles..."
 
-#: ../src/maemo-mapper.c:2989
-msgid "Dining"
-msgstr "Restaurantes"
+#: ../src/gps.c:779
+#, fuzzy
+msgid "Disconnecting from GPS receiver"
+msgstr "Buscando receptor GPS"
+
+#: ../src/poi.c:1740
+#, fuzzy
+msgid "Dist."
+msgstr "Distancia"
 
-#: ../src/maemo-mapper.c:3365 ../src/maemo-mapper.c:3425
-#: ../src/maemo-mapper.c:13566
+#: ../src/cmenu.c:136 ../src/path.c:517 ../src/path.c:577
 msgid "Distance"
 msgstr "Distancia"
 
-#: ../src/maemo-mapper.c:11354
+#: ../src/maps.c:1382
 msgid "Double Pixels"
 msgstr "Duplicar píxeles"
 
-#: ../src/maemo-mapper.c:12068
+#: ../src/main.c:195 ../src/menu.c:1466
+msgid "Down"
+msgstr ""
+
+#: ../src/maps.c:2069
 msgid "Download Maps"
 msgstr "Descargar mapas"
 
-#: ../src/maemo-mapper.c:10034
+#: ../src/poi.c:2202
+#, fuzzy
+msgid "Download POIs"
+msgstr "Descargar mapas"
+
+#: ../src/path.c:1071
 msgid "Download Route"
 msgstr "Descargar itinerario"
 
-#: ../src/maemo-mapper.c:6420 ../src/maemo-mapper.c:6451
-#: ../src/maemo-mapper.c:6475
+#: ../src/cmenu.c:603 ../src/cmenu.c:634 ../src/cmenu.c:658
 msgid "Download Route to..."
 msgstr "Descargar itinerario a..."
 
-#: ../src/maemo-mapper.c:11317
+#: ../src/maps.c:1345
 msgid "Download Zoom Steps"
 msgstr "Intervalos a descargar"
 
-#: ../src/maemo-mapper.c:6129 ../src/maemo-mapper.c:11567
+#: ../src/maps.c:1595 ../src/menu.c:1361 ../src/menu.c:1401
 msgid "Download..."
 msgstr "Descargar..."
 
-#: ../src/maemo-mapper.c:6937
-msgid "Downloading maps"
-msgstr "Descargando mapas"
+#: ../src/maps.c:654 ../src/maps.c:667
+msgid "Downloaded maps will not be cached."
+msgstr ""
 
-#: ../src/maemo-mapper.c:12913
-msgid "Edit"
-msgstr "Editar"
+#: ../src/menu.c:1479
+#, fuzzy
+msgid "East"
+msgstr "Desplazarse al este"
 
-#: ../src/maemo-mapper.c:13208
+#: ../src/poi.c:1170
 msgid "Edit Categories..."
 msgstr "Editar categorías..."
 
-#: ../src/maemo-mapper.c:12625
+#: ../src/poi.c:579
 msgid "Edit Category"
 msgstr "Editar categoría"
 
-#: ../src/maemo-mapper.c:13118
+#: ../src/poi.c:1090
 msgid "Edit POI"
 msgstr "Editar Pto de interés"
 
-#: ../src/maemo-mapper.c:3000
+#: ../src/poi.c:875 ../src/poi.c:1999
+#, fuzzy
+msgid "Edit..."
+msgstr "Ver/editar..."
+
+#: ../src/poi.c:157
 msgid "Elementary schools, college campuses, etc."
 msgstr "Colegios, institutos, facultades, etc."
 
-#: ../src/maemo-mapper.c:6270
+#: ../src/menu.c:1574
 msgid "Enable GPS"
 msgstr "Activar GPS"
 
-#: ../src/maemo-mapper.c:5042
+#: ../src/settings.c:1139
 msgid "Enable Voice Synthesis (requires flite)"
 msgstr "Activar síntesis de voz (requiere flite)"
 
-#: ../src/maemo-mapper.c:12693 ../src/maemo-mapper.c:12945
+#: ../src/poi.c:647 ../src/poi.c:907
 msgid "Enabled"
 msgstr "Activado"
 
-#: ../src/maemo-mapper.c:7185
-msgid ""
-"Error in download.  Check internet connection and/or Map Repository URL "
-"Format."
+#: ../src/poi.c:1305
+#, fuzzy
+msgid "Error adding POI"
+msgstr "Hubo un problema al añadir el punto de interés"
+
+#: ../src/poi.c:710
+#, fuzzy
+msgid "Error adding category"
+msgstr "Hubo un problema al añadir la categoría"
+
+#: ../src/gps.c:631
+#, fuzzy
+msgid "Error connecting to GPS receiver."
+msgstr "Ha fallado la conexión al receptor GPS. ¿Desea reintentarla?"
+
+#: ../src/gps.c:617
+msgid "Error connecting to GPSD."
 msgstr ""
-"Error en la descarga. Compruebe la conexión a internet o el formato de la "
-"dirección del repositorio."
 
-#: ../src/maemo-mapper.c:8371 ../src/maemo-mapper.c:10319
-#: ../src/maemo-mapper.c:10363 ../src/maemo-mapper.c:10437
+#: ../src/poi.c:521 ../src/poi.c:969 ../src/poi.c:1871
+#, fuzzy
+msgid "Error deleting POI"
+msgstr "Hubo un problema al eliminar el punto de interés"
+
+#: ../src/poi.c:530
+#, fuzzy
+msgid "Error deleting category"
+msgstr "Hubo un problema al eliminar la categoría"
+
+#: ../src/main.c:488 ../src/menu.c:122 ../src/menu.c:234 ../src/path.c:678
+#: ../src/poi.c:2130 ../src/poi.c:2481
 msgid "Error parsing GPX file."
 msgstr "Erro al procesar el archivo GPX."
 
-#: ../src/maemo-mapper.c:1501
+#: ../src/gps.c:667
+#, fuzzy
+msgid "Error reading GPS data."
+msgstr "Erro al procesar el archivo GPX."
+
+#: ../src/poi.c:754
+#, fuzzy
+msgid "Error updating Category"
+msgstr "Hubo un problema al actualizar la categoría"
+
+#: ../src/poi.c:1285 ../src/poi.c:1583
+#, fuzzy
+msgid "Error updating POI"
+msgstr "Hubo un problema al actualizar el punto de interés"
+
+#: ../src/poi.c:695
+#, fuzzy
+msgid "Error updating category"
+msgstr "Hubo un problema al actualizar la categoría"
+
+#: ../src/gpx.c:478 ../src/gpx.c:805
 msgid "Error while writing to file"
 msgstr "Error al escribir en el archivo"
 
-#: ../src/maemo-mapper.c:10459 ../src/maemo-mapper.c:10618
+#: ../src/poi.c:103
+#, fuzzy
+msgid "Error with POI database"
+msgstr "Hubo un problema con la base de datos de puntos de interés"
+
+#: ../src/menu.c:153 ../src/menu.c:256 ../src/poi.c:1911
 msgid "Error writing GPX file."
 msgstr "Error al escribir el archivo GPX."
 
-#: ../src/maemo-mapper.c:3148
+#: ../src/gps.c:801
 msgid "Establishing GPS fix"
 msgstr "Calibrando GPS"
 
-#: ../src/maemo-mapper.c:2290
+#: ../src/display.c:282
 msgid "Estimated"
 msgstr "Estimado"
 
-#: ../src/maemo-mapper.c:3903
-msgid "Failed to connect to GPS receiver.  Retry?"
+#: ../src/poi.c:1948
+msgid "Export to GPX..."
+msgstr ""
+
+#: ../src/gps.c:923
+#, fuzzy
+msgid "Failed to connect to Bluetooth GPS receiver."
 msgstr "Ha fallado la conexión al receptor GPS. ¿Desea reintentarla?"
 
-#: ../src/maemo-mapper.c:10251 ../src/maemo-mapper.c:10957
+#: ../src/util.c:139
 msgid "Failed to connect to GPX Directions server"
 msgstr "Ha fallado la conexión al servidor de direcciones GPX"
 
-#: ../src/maemo-mapper.c:5577
+#: ../src/settings.c:1646
 msgid "Failed to initialize GConf.  Quitting."
 msgstr "Ha fallado la inicialización de GConf. Saliendo."
 
-#: ../src/maemo-mapper.c:4047
+#: ../src/settings.c:72
 msgid "Failed to initialize GConf.  Settings were not saved."
 msgstr ""
 "Ha fallado la inicialización de GConf. No se han grabado las preferencias."
 
-#: ../src/maemo-mapper.c:7750 ../src/maemo-mapper.c:8360
+#: ../src/display.c:2561 ../src/main.c:476
 msgid "Failed to open file for reading"
 msgstr "El archivo no pudo ser abierto para lectura"
 
-#: ../src/maemo-mapper.c:7403 ../src/maemo-mapper.c:7751
+#: ../src/display.c:2562
 msgid "Failed to open file for writing"
 msgstr "El archivo no pudo ser abierto para escritura"
 
-#: ../src/maemo-mapper.c:3014
+#: ../src/maps.c:652 ../src/maps.c:666
+#, fuzzy
+msgid "Failed to open map database for repository"
+msgstr "No se pudo abrir o crear la base de datos"
+
+#: ../src/poi.c:171
 msgid "Failed to open or create database"
 msgstr "No se pudo abrir o crear la base de datos"
 
-#: ../src/maemo-mapper.c:1502
+#: ../src/path.c:1553
+msgid "Failed to open path database. Tracks and routes will not be saved."
+msgstr ""
+
+#: ../src/path.c:195 ../src/path.c:221 ../src/path.c:240
+msgid "Failed to write to path database. Tracks and routes may not be saved."
+msgstr ""
+
+#: ../src/main.c:312
+msgid "File"
+msgstr ""
+
+#: ../src/settings.c:1044
+msgid "File Path"
+msgstr ""
+
+#: ../src/gpx.c:479 ../src/gpx.c:806
 msgid "File is incomplete."
 msgstr "El archivo está incompleto."
 
-#: ../src/maemo-mapper.c:2858
+#: ../src/display.c:850
 msgid "Fix"
 msgstr "Calibrado"
 
-#: ../src/maemo-mapper.c:2867
+#: ../src/display.c:859
 msgid "Fix Quality"
 msgstr "Calidad del calibrado"
 
-#: ../src/maemo-mapper.c:2289
+#: ../src/settings.c:1093
+#, fuzzy
+msgid "Fixed"
+msgstr "Calibrado"
+
+#: ../src/display.c:281
 #, fuzzy
 msgid "Float RTK"
 msgstr "Float RTK"
 
-#: ../src/maemo-mapper.c:13442
+#: ../src/display.c:2444
 msgid "Format"
 msgstr "Formato de la URL"
 
-#: ../src/maemo-mapper.c:2985
-msgid "Fuel"
-msgstr "Gasolineras"
-
-#: ../src/maemo-mapper.c:6189
+#: ../src/menu.c:1564
 msgid "Full Screen"
 msgstr "Pantalla completa"
 
-#: ../src/maemo-mapper.c:4747 ../src/maemo-mapper.c:4964
-#: ../src/maemo-mapper.c:6266
+#: ../src/menu.c:1570 ../src/settings.c:778 ../src/settings.c:1004
 msgid "GPS"
 msgstr "GPS"
 
-#: ../src/maemo-mapper.c:2761
+#: ../src/display.c:753
 msgid "GPS Details"
 msgstr "Detalles del GPS"
 
-#: ../src/maemo-mapper.c:2774
+#: ../src/display.c:766
 msgid "GPS Information"
 msgstr "Información del GPS"
 
-#: ../src/maemo-mapper.c:6258 ../src/maemo-mapper.c:12151
+#: ../src/maps.c:2152 ../src/menu.c:1491
 msgid "GPS Location"
 msgstr "Localización del GPS"
 
-#: ../src/maemo-mapper.c:3004
+#: ../src/main.c:311
+#, fuzzy
+msgid "GPSD"
+msgstr "GPS"
+
+#: ../src/settings.c:1025
+msgid "GPSD Host"
+msgstr ""
+
+#: ../src/poi.c:161
 msgid "General landmarks."
 msgstr "Puntos generales de referencia."
 
-#: ../src/maemo-mapper.c:3002
+#: ../src/poi.c:159
 msgid "General places of business."
 msgstr "Sitios generales de negocios."
 
-#: ../src/maemo-mapper.c:6250
+#: ../src/menu.c:1483 ../src/poi.c:1996
 msgid "Go to"
 msgstr "Ir a"
 
-#: ../src/maemo-mapper.c:10900
+#: ../src/menu.c:827
 msgid "Go to Address"
 msgstr "Ir a la dirección"
 
-#: ../src/maemo-mapper.c:10806
+#: ../src/menu.c:731
 msgid "Go to Lat/Lon"
 msgstr "Ir a Lat/Lon"
 
-#: ../src/maemo-mapper.c:6483
+#: ../src/cmenu.c:666
 msgid "Go to Nearest"
 msgstr "Ir al más cercano"
 
-#: ../src/maemo-mapper.c:6460
+#: ../src/cmenu.c:643
 msgid "Go to Next"
 msgstr "Ir al siguiente"
 
-#: ../src/maemo-mapper.c:4608
+#: ../src/settings.c:644
 msgid "Hardware Keys"
 msgstr "Teclas hardware"
 
-#: ../src/maemo-mapper.c:4950
+#: ../src/settings.c:990
 msgid "Hardware Keys..."
 msgstr "Teclas hardware..."
 
-#: ../src/maemo-mapper.c:2822
+#: ../src/display.c:814
 msgid "Heading"
 msgstr "Encabezado"
 
-#: ../src/maemo-mapper.c:6291
+#: ../src/menu.c:1595
 msgid "Help..."
 msgstr "Ayuda..."
 
-#: ../src/maemo-mapper.c:2988
+#: ../src/poi.c:145
 msgid "Houses, apartments, or other residences of import."
 msgstr "Viviendas, apartamentos u otros lugares de residencia significativos."
 
-#: ../src/maemo-mapper.c:12937
+#: ../src/poi.c:899
 msgid "ID"
 msgstr "ID"
 
-#: ../src/maemo-mapper.c:2994
+#: ../src/menu.c:1399
+msgid "Import..."
+msgstr ""
+
+#: ../src/poi.c:151
 msgid "Indoor or Outdoor places to have fun."
 msgstr "Sitios de ocio en interiores o al aire libre."
 
-#: ../src/maemo-mapper.c:5102
-msgid "Information Font Size"
+#: ../src/settings.c:1174
+#, fuzzy
+msgid "Info Font Size"
 msgstr "Tamaño de letra de las informaciones"
 
-#: ../src/maemo-mapper.c:6151
+#: ../src/menu.c:1383
 msgid "Insert Break"
 msgstr "Insertar parada"
 
-#: ../src/maemo-mapper.c:10493
+#: ../src/menu.c:290
 msgid "Insert Mark"
 msgstr "Insertar marca"
 
-#: ../src/maemo-mapper.c:6153
+#: ../src/menu.c:1385
 msgid "Insert Mark..."
 msgstr "Insertar marca..."
 
-#: ../src/maemo-mapper.c:8059
+#: ../src/main.c:268
 msgid "Insert Track Break"
 msgstr "Insertar parada en la traza"
 
-#: ../src/maemo-mapper.c:12324
+#: ../src/maps.c:2342
 msgid "Invalid Bottom-Right Latitude"
 msgstr "Latitud inferior derecha inválida"
 
-#: ../src/maemo-mapper.c:12331
+#: ../src/maps.c:2349
 msgid "Invalid Bottom-Right Longitude"
 msgstr "Longitud inferior derecha inválida"
 
-#: ../src/maemo-mapper.c:10865 ../src/maemo-mapper.c:13267
+#: ../src/menu.c:792 ../src/poi.c:1224
 msgid "Invalid Latitude"
 msgstr "Latitud inválida"
 
-#: ../src/maemo-mapper.c:10872 ../src/maemo-mapper.c:13274
+#: ../src/menu.c:799 ../src/poi.c:1231
 msgid "Invalid Longitude"
 msgstr "Longitud inválida"
 
-#: ../src/maemo-mapper.c:9534 ../src/maemo-mapper.c:9545
+#: ../src/gps.c:66 ../src/gps.c:77
 msgid "Invalid NMEA input from receiver!"
 msgstr "¡NMEA del receptor inválido!"
 
-#: ../src/maemo-mapper.c:12310
+#: ../src/maps.c:2328
 msgid "Invalid Top-Left Latitude"
 msgstr "Latitud superior izquierda inválida"
 
-#: ../src/maemo-mapper.c:12317
+#: ../src/maps.c:2335
 msgid "Invalid Top-Left Longitude"
 msgstr "Longitud superior izquierda inválida"
 
-#: ../src/maemo-mapper.c:10971
+#: ../src/util.c:150
 msgid "Invalid address."
 msgstr "Dirección inválida."
 
-#: ../src/maemo-mapper.c:10264
+#: ../src/poi.c:2460
+#, fuzzy
+msgid "Invalid origin or query."
+msgstr "Longitud inválida"
+
+#: ../src/path.c:657
 msgid "Invalid source or destination."
 msgstr "Origen o destino inválidos."
 
-#: ../src/maemo-mapper.c:6562
+#: ../src/display.c:1077
 msgid ""
 "It looks like this is your first time running Maemo Mapper.  Press OK to "
 "view the the help pages. Otherwise, press Cancel to continue."
@@ -592,79 +768,82 @@ msgstr ""
 "si desea ver las páginas de ayuda. En caso contrario, presione Cancelar para "
 "continuar."
 
-#: ../src/maemo-mapper.c:5094
-msgid "Keep Display On Only in Fullscreen Mode"
-msgstr "Mantener display sólo en modo pantalla completa"
-
-#: ../src/maemo-mapper.c:8592 ../src/maemo-mapper.c:12661
-#: ../src/maemo-mapper.c:12950 ../src/maemo-mapper.c:13177
+#: ../src/poi.c:453 ../src/poi.c:615 ../src/poi.c:912 ../src/poi.c:1151
+#: ../src/poi.c:1757
 msgid "Label"
 msgstr "Etiqueta"
 
-#: ../src/maemo-mapper.c:3003
+#: ../src/poi.c:160
 msgid "Landmark"
 msgstr "Punto de referencia"
 
-#: ../src/maemo-mapper.c:13161 ../src/maemo-mapper.c:13424
+#: ../src/display.c:2426 ../src/poi.c:1135
 msgid "Lat"
 msgstr "Lat"
 
-#: ../src/maemo-mapper.c:10503 ../src/maemo-mapper.c:13611
+#: ../src/menu.c:300 ../src/path.c:1344
 msgid "Lat, Lon:"
 msgstr "Lat, Lon:"
 
-#: ../src/maemo-mapper.c:6231
+#: ../src/menu.c:1544
 msgid "Lat/Lon"
 msgstr "Lat/Lon"
 
-#: ../src/maemo-mapper.c:6254
+#: ../src/menu.c:1487
 msgid "Lat/Lon..."
 msgstr "Lat/Lon..."
 
-#: ../src/maemo-mapper.c:2786 ../src/maemo-mapper.c:10816
-#: ../src/maemo-mapper.c:12141 ../src/maemo-mapper.c:13512
+#: ../src/cmenu.c:82 ../src/display.c:778 ../src/maps.c:2142 ../src/menu.c:741
 msgid "Latitude"
 msgstr "Latitud"
 
-#: ../src/maemo-mapper.c:6237
+#: ../src/menu.c:1550
 msgid "Lead"
 msgstr "Frente"
 
-#: ../src/maemo-mapper.c:5011
+#: ../src/settings.c:1078
 msgid "Lead Amount"
 msgstr "Espacio frontal"
 
-#: ../src/maemo-mapper.c:5082
+#: ../src/main.c:196 ../src/menu.c:1468
+#, fuzzy
+msgid "Left"
+msgstr "Superior izquierda"
+
+#: ../src/settings.c:1151
 msgid "Line Width"
 msgstr "Anchura de las líneas"
 
-#: ../src/maemo-mapper.c:2831
+#: ../src/display.c:823
 msgid "Local time"
 msgstr "Hora local"
 
-#: ../src/maemo-mapper.c:5162 ../src/maemo-mapper.c:6409
-#: ../src/maemo-mapper.c:8587
+#: ../src/cmenu.c:592 ../src/poi.c:448 ../src/settings.c:1249
 msgid "Location"
 msgstr "Lugar"
 
-#: ../src/maemo-mapper.c:2997
+#: ../src/poi.c:154
 msgid "Lodging"
 msgstr "Alojamiento"
 
-#: ../src/maemo-mapper.c:13169 ../src/maemo-mapper.c:13433
+#: ../src/display.c:2435 ../src/poi.c:1143
 msgid "Lon"
 msgstr "Lon"
 
-#: ../src/maemo-mapper.c:2795 ../src/maemo-mapper.c:10829
-#: ../src/maemo-mapper.c:12145 ../src/maemo-mapper.c:13513
+#: ../src/cmenu.c:83 ../src/display.c:787 ../src/maps.c:2146 ../src/menu.c:755
 msgid "Longitude"
 msgstr "Longitud"
 
-#: ../src/maemo-mapper.c:4484 ../src/maemo-mapper.c:4968
+#: ../src/settings.c:531
 msgid "MAC"
 msgstr "MAC"
 
-#: ../src/maemo-mapper.c:11470
+#: ../src/settings.c:1009
+#, fuzzy
+msgid "MAC Address"
+msgstr "Dirección"
+
+#: ../src/maps.c:1498
 msgid ""
 "Maemo Mapper will now download and add a list of possibly-duplicate "
 "repositories from the internet.  Continue?"
@@ -672,47 +851,47 @@ msgstr ""
 "Maemo Mapper descargará y añadirá una lista de repositorios (posiblemente "
 "duplicados) desde Internet. ¿Desea continuar?"
 
-#: ../src/maemo-mapper.c:12033
+#: ../src/maps.c:2034
 msgid "Manage Maps"
 msgstr "Gestionar mapas"
 
-#: ../src/maemo-mapper.c:6168
+#: ../src/menu.c:1415
 msgid "Manage Maps..."
 msgstr "Gestionar mapas..."
 
-#: ../src/maemo-mapper.c:11550
+#: ../src/maps.c:1578
 msgid "Manage Repositories"
 msgstr "Gestionar repositorios"
 
-#: ../src/maemo-mapper.c:6170
+#: ../src/menu.c:1417
 msgid "Manage Repositories..."
 msgstr "Gestionar repositorios..."
 
-#: ../src/maemo-mapper.c:2291
+#: ../src/display.c:283
 msgid "Manual"
 msgstr "Manual"
 
-#: ../src/maemo-mapper.c:6163
+#: ../src/menu.c:1410
 msgid "Maps"
 msgstr "Mapas"
 
-#: ../src/maemo-mapper.c:2876
+#: ../src/display.c:868
 msgid "Max speed"
 msgstr "Máxima velocidad"
 
-#: ../src/maemo-mapper.c:5078
+#: ../src/settings.c:1147
 msgid "Misc."
 msgstr "Misc."
 
-#: ../src/maemo-mapper.c:5114
+#: ../src/settings.c:1204
 msgid "Misc. 2"
 msgstr "Misc. 2"
 
-#: ../src/maemo-mapper.c:3006
+#: ../src/poi.c:163
 msgid "Miscellaneous category for everything else."
 msgstr "Categoría miscelánea para todo lo demás."
 
-#: ../src/maemo-mapper.c:12285 ../src/maemo-mapper.c:12449
+#: ../src/maps.c:2294 ../src/menu.c:520
 msgid ""
 "NOTE: You must set a Map URI in the current repository in order to download "
 "maps."
@@ -720,63 +899,66 @@ msgstr ""
 "NOTA: Debe indicar una dirección de internet en el repositorio actual para "
 "poder descargar mapas."
 
-#: ../src/maemo-mapper.c:11171 ../src/maemo-mapper.c:11409
+#: ../src/maps.c:1197 ../src/maps.c:1437
 msgid "Name"
 msgstr "Nombre"
 
-#: ../src/maemo-mapper.c:6262
+#: ../src/menu.c:1495
 msgid "Nearest POI"
 msgstr "Pto. de interés más cercano"
 
-#: ../src/maemo-mapper.c:11161
+#: ../src/maps.c:1187
 msgid "New Name"
 msgstr "Nuevo nombre"
 
-#: ../src/maemo-mapper.c:11399
+#: ../src/maps.c:1427
 msgid "New Repository"
 msgstr "Nuevo repositorio"
 
-#: ../src/maemo-mapper.c:11589
+#: ../src/maps.c:1617
 msgid "New..."
 msgstr "Nuevo..."
 
-#: ../src/maemo-mapper.c:6260
+#: ../src/menu.c:1493
 msgid "Next Waypoint"
 msgstr "Siguiente etapa"
 
-#: ../src/maemo-mapper.c:11362
+#: ../src/maps.c:1390
 msgid "Next-able"
 msgstr "Siguiente"
 
-#: ../src/maemo-mapper.c:5283
+#: ../src/settings.c:1472
+#, fuzzy
 msgid ""
-"No GPS Receiver MAC provided.\n"
+"No GPS Receiver provided.\n"
 "GPS will be disabled."
 msgstr ""
 "No se ha proporcionado ninguna MAC del receptor GPS.\n"
 "Se deshabilitará el GPS."
 
-#: ../src/maemo-mapper.c:8530 ../src/maemo-mapper.c:11082
+#: ../src/menu.c:950 ../src/poi.c:391 ../src/poi.c:2772
 msgid "No POIs found."
 msgstr "No se han encontrado puntos de interés."
 
-#: ../src/maemo-mapper.c:6243
+#: ../src/poi.c:1401
+#, fuzzy
+msgid "No POIs were found."
+msgstr "No se han encontrado puntos de interés."
+
+#: ../src/main.c:309 ../src/menu.c:1556
 msgid "None"
 msgstr "Ninguno"
 
-#: ../src/maemo-mapper.c:4984
-msgid ""
-"Note: You can enter a device path\n"
-"(e.g. \"/dev/rfcomm0\")."
-msgstr ""
-"Nota: Puede introducir una ruta a un dispositivo\n"
-"(Ej.: \"/dev/rfcomm0\")."
+#: ../src/menu.c:1473
+#, fuzzy
+msgid "North"
+msgstr "Desplazarse al norte"
 
-#: ../src/maemo-mapper.c:6127 ../src/maemo-mapper.c:6147
+#: ../src/menu.c:1359 ../src/menu.c:1379
 msgid "Open..."
 msgstr "Abrir..."
 
-#: ../src/maemo-mapper.c:6572
+#: ../src/display.c:1087
 msgid ""
 "OpenStreetMap.org provides public, free-to-use maps.  You can also download "
 "a sample set of repositories from  the internet by using the \"Download...\" "
@@ -786,512 +968,602 @@ msgstr ""
 "descargar un conjunto de repositorios de ejemplo de Internet usando el botón "
 "\"Descargar...\"."
 
-#: ../src/maemo-mapper.c:10083
+#: ../src/path.c:1126 ../src/poi.c:2268 ../src/poi.c:2565
 msgid "Origin"
 msgstr "Origen"
 
-#: ../src/maemo-mapper.c:3005
+#: ../src/poi.c:162
 msgid "Other"
 msgstr "Otros"
 
-#: ../src/maemo-mapper.c:12075
+#: ../src/maps.c:2076
 msgid "Overwrite"
 msgstr "Sobreescribir"
 
-#: ../src/maemo-mapper.c:4792 ../src/maemo-mapper.c:5177
-#: ../src/maemo-mapper.c:6464
+#: ../src/cmenu.c:647 ../src/menu.c:1395 ../src/menu.c:1534
+#: ../src/settings.c:823 ../src/settings.c:1264
 msgid "POI"
 msgstr "Pto. de interés"
 
-#: ../src/maemo-mapper.c:12903
+#: ../src/poi.c:865
 msgid "POI Categories"
 msgstr "Categorías de ptos. de interés"
 
-#: ../src/maemo-mapper.c:6222
-msgid "POI Categories..."
-msgstr "Categorías de puntos de interés..."
+#: ../src/poi.c:1987
+#, fuzzy
+msgid "POI List"
+msgstr "Puntos de interés"
 
-#: ../src/maemo-mapper.c:5181
+#: ../src/settings.c:1268
 msgid "POI database"
 msgstr "BB.DD. de ptos. de interés"
 
-#: ../src/maemo-mapper.c:6218
-msgid "POIs"
-msgstr "Puntos de interés"
+#: ../src/poi.c:1907
+msgid "POIs Exported"
+msgstr ""
+
+#: ../src/poi.c:1395
+msgid ""
+"POIs were added to the POI database.  The following screen will allow you to "
+"modify or delete any of the new POIs."
+msgstr ""
 
-#: ../src/maemo-mapper.c:2287
+#: ../src/display.c:279
 msgid "PPS"
 msgstr "PPS"
 
-#: ../src/maemo-mapper.c:8044
+#: ../src/poi.c:2252
+msgid "Page"
+msgstr ""
+
+#: ../src/menu.c:1460
+msgid "Pan"
+msgstr ""
+
+#: ../src/main.c:245
 msgid "Pan East"
 msgstr "Desplazarse al este"
 
-#: ../src/maemo-mapper.c:8041
+#: ../src/main.c:242
 msgid "Pan North"
 msgstr "Desplazarse al norte"
 
-#: ../src/maemo-mapper.c:8043
+#: ../src/settings.c:1065
+#, fuzzy
+msgid "Pan Sensitivity"
+msgstr "Sensitividad"
+
+#: ../src/main.c:244
 msgid "Pan South"
 msgstr "Desplazarse al sur"
 
-#: ../src/maemo-mapper.c:8042
+#: ../src/main.c:243
 msgid "Pan West"
 msgstr "Desplazarse al oeste"
 
-#  This word refers to Pitch as in of a person's voice.
-#: ../src/maemo-mapper.c:5067
-msgid "Pitch"
-msgstr "Tono"
-
-#: ../src/maemo-mapper.c:2990
+#: ../src/poi.c:147
 msgid "Places to eat or drink."
 msgstr "Lugares donde comer o beber."
 
-#: ../src/maemo-mapper.c:2992
+#: ../src/poi.c:149
 msgid "Places to shop or acquire services."
 msgstr "Lugares de compras o servicios."
 
-#: ../src/maemo-mapper.c:2998
+#: ../src/poi.c:155
 msgid "Places to stay temporarily or for the night."
 msgstr "Lugares donde pernoctar o residir temporalmente."
 
-#: ../src/maemo-mapper.c:10567
+#: ../src/menu.c:364
 msgid "Please provide a description for the mark."
 msgstr "Por favor, introduzca una descripción para la marca."
 
-#: ../src/maemo-mapper.c:4519
+#: ../src/settings.c:566
 msgid "Please select a bluetooth device from the list."
 msgstr "Por favor, seleccione una dispositivo bluetooth de la lista."
 
-#: ../src/maemo-mapper.c:13289
-msgid "Please specify a category for the POI."
+#: ../src/poi.c:1250 ../src/poi.c:1532
+#, fuzzy
+msgid "Please specify a category."
 msgstr "Por favor, especifique una categoría para el punto de interés."
 
-#: ../src/maemo-mapper.c:13282
-msgid "Please specify a name for the POI."
-msgstr "Por favor, especifique un nombre para el punto de interés."
+#: ../src/poi.c:2104 ../src/poi.c:2425
+#, fuzzy
+msgid "Please specify a default category."
+msgstr "Por favor, especifique un nombre para la categoría."
 
-#: ../src/maemo-mapper.c:12719
+#: ../src/poi.c:673
 msgid "Please specify a name for the category."
 msgstr "Por favor, especifique un nombre para la categoría."
 
-#: ../src/maemo-mapper.c:10173
+#: ../src/poi.c:1243
+#, fuzzy
+msgid "Please specify a name."
+msgstr "Por favor, especifique una dirección"
+
+#: ../src/poi.c:2432
+#, fuzzy
+msgid "Please specify a query."
+msgstr "Por favor, especifique una dirección fuente."
+
+#: ../src/path.c:1214 ../src/poi.c:2368
 msgid "Please specify a source URL."
 msgstr "Por favor, especifique una dirección fuente."
 
-#: ../src/maemo-mapper.c:10217
+#: ../src/path.c:1256
 msgid "Please specify a start location."
 msgstr "Por favor, especifique un lugar de salida."
 
-#: ../src/maemo-mapper.c:10941
-msgid "Please specify an address."
-msgstr "Por favor, especifique una dirección"
-
-#: ../src/maemo-mapper.c:10224
+#: ../src/path.c:1263
 msgid "Please specify an end location."
 msgstr "Por favor, especifique un lugar de llegada."
 
-#: ../src/maemo-mapper.c:13340
-msgid "Problem adding POI"
-msgstr "Hubo un problema al añadir el punto de interés"
-
-#: ../src/maemo-mapper.c:12756
-msgid "Problem adding category"
-msgstr "Hubo un problema al añadir la categoría"
-
-#: ../src/maemo-mapper.c:12567 ../src/maemo-mapper.c:13019
-msgid "Problem deleting POI"
-msgstr "Hubo un problema al eliminar el punto de interés"
-
-#: ../src/maemo-mapper.c:12576
-msgid "Problem deleting category"
-msgstr "Hubo un problema al eliminar la categoría"
+#: ../src/poi.c:2419 ../src/poi.c:2696
+#, fuzzy
+msgid "Please specify an origin."
+msgstr "Por favor, especifique un lugar de llegada."
 
-#: ../src/maemo-mapper.c:12795
-msgid "Problem updating Category"
-msgstr "Hubo un problema al actualizar la categoría"
+#: ../src/settings.c:1110
+msgid "Points"
+msgstr ""
 
-#: ../src/maemo-mapper.c:13318
-msgid "Problem updating POI"
-msgstr "Hubo un problema al actualizar el punto de interés"
+#: ../src/settings.c:1035
+#, fuzzy
+msgid "Port"
+msgstr "Desplazarse al norte"
 
-#: ../src/maemo-mapper.c:12741
-msgid "Problem updating category"
-msgstr "Hubo un problema al actualizar la categoría"
+#: ../src/maps.c:850
+msgid "Processing Maps"
+msgstr ""
 
-#: ../src/maemo-mapper.c:2946
-msgid "Problem with POI database"
-msgstr "Hubo un problema con la base de datos de puntos de interés"
+#: ../src/poi.c:2278 ../src/poi.c:2575
+msgid "Query"
+msgstr ""
 
-#: ../src/maemo-mapper.c:2288
+#: ../src/display.c:280
 msgid "Real Time Kinematic"
 msgstr "Cinemática de tiempo real"
 
-#: ../src/maemo-mapper.c:3723
+#: ../src/path.c:919
 msgid "Really clear the track?"
 msgstr "¿Esta seguro de que desea borrar la traza?"
 
-#: ../src/maemo-mapper.c:3678
+#: ../src/path.c:798
 msgid "Recalculating directions..."
 msgstr "Recalculando direcciones..."
 
-#: ../src/maemo-mapper.c:2993
+#: ../src/poi.c:150
 msgid "Recreation"
 msgstr "Ocio"
 
-#: ../src/maemo-mapper.c:11583
+#: ../src/maps.c:1611
 msgid "Rename..."
 msgstr "Renombrar..."
 
-#: ../src/maemo-mapper.c:11440
+#: ../src/maps.c:1468
 msgid "Replace all repositories with the default repository?"
 msgstr ""
 "¿Desea reemplazar todos los repositorios por el repositorio por defecto?"
 
-#: ../src/maemo-mapper.c:6137
+#: ../src/menu.c:1369 ../src/menu.c:1452
 msgid "Reset"
 msgstr "Reiniciar"
 
-#: ../src/maemo-mapper.c:6281 ../src/maemo-mapper.c:8069
+#: ../src/main.c:278 ../src/menu.c:1585
 msgid "Reset Bluetooth"
 msgstr "Reiniciar Bluetooth"
 
-#: ../src/maemo-mapper.c:4699
+#: ../src/main.c:247
+msgid "Reset Viewing Angle"
+msgstr ""
+
+#: ../src/settings.c:730
 msgid "Reset all colors to their original defaults?"
 msgstr "¿Desea reiniciar todos los colores a los valores por defecto?"
 
-#: ../src/maemo-mapper.c:4580
+#: ../src/settings.c:616
 msgid "Reset all hardware keys to their original defaults?"
 msgstr "¿Desea reiniciar todas las teclas hardware a los valores por defecto?"
 
-#: ../src/maemo-mapper.c:4614 ../src/maemo-mapper.c:4735
-#: ../src/maemo-mapper.c:11561
+#: ../src/maps.c:1589 ../src/settings.c:650 ../src/settings.c:766
 msgid "Reset..."
 msgstr "Reiniciar..."
 
-#: ../src/maemo-mapper.c:2987
+#: ../src/poi.c:144
 msgid "Residence"
 msgstr "Vivienda"
 
-#: ../src/maemo-mapper.c:4777 ../src/maemo-mapper.c:6123
-#: ../src/maemo-mapper.c:6204
+#: ../src/poi.c:146
+msgid "Restaurant"
+msgstr ""
+
+#: ../src/main.c:194 ../src/menu.c:1470
+#, fuzzy
+msgid "Right"
+msgstr "Superior derecha"
+
+#: ../src/menu.c:1444
+#, fuzzy
+msgid "Rotate"
+msgstr "Itinerario"
+
+#: ../src/settings.c:1097
+#, fuzzy
+msgid "Rotate Sensit."
+msgstr "Sensitividad"
+
+#: ../src/main.c:249
+msgid "Rotate View Clockwise"
+msgstr ""
+
+#: ../src/main.c:251
+msgid "Rotate View Counter-Clockwise"
+msgstr ""
+
+#: ../src/menu.c:1355 ../src/menu.c:1520 ../src/settings.c:808
 msgid "Route"
 msgstr "Itinerario"
 
-#: ../src/maemo-mapper.c:10311
+#: ../src/path.c:672
 msgid "Route Downloaded"
 msgstr "Itinerario descargado"
 
-#: ../src/maemo-mapper.c:8368 ../src/maemo-mapper.c:10360
+#: ../src/main.c:485 ../src/menu.c:119
 msgid "Route Opened"
 msgstr "Itinerario abierto"
 
-#: ../src/maemo-mapper.c:10615
+#: ../src/menu.c:150
 msgid "Route Saved"
 msgstr "Itinerario guardado"
 
-#: ../src/maemo-mapper.c:10705
+#: ../src/menu.c:1048
 msgid "Routes are now hidden"
 msgstr "Se han ocultado los itinerarios"
 
-#: ../src/maemo-mapper.c:10699
+#: ../src/menu.c:1042
 msgid "Routes are now shown"
 msgstr "Se muestran los itinerarios"
 
-#: ../src/maemo-mapper.c:2285
+#: ../src/display.c:277
 msgid "SPS"
 msgstr "SPS"
 
-#: ../src/maemo-mapper.c:2849
+#: ../src/display.c:841
 msgid "Sat in use"
 msgstr "Sat. en uso"
 
-#: ../src/maemo-mapper.c:2840
+#: ../src/display.c:832
 msgid "Sat in view"
 msgstr "Sat. visibles"
 
-#: ../src/maemo-mapper.c:2781
+#: ../src/display.c:773
 msgid "Satellites details"
 msgstr "Detalles de los satélites"
 
-#: ../src/maemo-mapper.c:2707
+#: ../src/display.c:699
 msgid "Satellites in view"
 msgstr "Satélites visibles"
 
-#: ../src/maemo-mapper.c:6131 ../src/maemo-mapper.c:6149
+#: ../src/menu.c:1363 ../src/menu.c:1381
 msgid "Save..."
 msgstr "Guardar..."
 
-#: ../src/maemo-mapper.c:6199
+#: ../src/menu.c:1510
 msgid "Scale"
 msgstr "Escala"
 
-#: ../src/maemo-mapper.c:4978
+#: ../src/settings.c:1019
 msgid "Scan..."
 msgstr "Buscar..."
 
-#: ../src/maemo-mapper.c:4495
+#: ../src/settings.c:542
 msgid "Scanning for Bluetooth Devices"
 msgstr "Buscando dispositivos Bluetooth"
 
-#: ../src/maemo-mapper.c:2999
+#: ../src/poi.c:156
 msgid "School"
 msgstr "Educación"
 
-#: ../src/maemo-mapper.c:3138
+#: ../src/gps.c:790
 msgid "Searching for GPS receiver"
 msgstr "Buscando receptor GPS"
 
-#: ../src/maemo-mapper.c:4459
+#: ../src/settings.c:506
 msgid "Select Bluetooth Device"
 msgstr "Seleccionar dispositivo Bluetooth"
 
-#: ../src/maemo-mapper.c:8054
+#: ../src/main.c:263
 msgid "Select Next Repository"
 msgstr "Seleccionar siguiente repositorio"
 
-#: ../src/maemo-mapper.c:8560
+#: ../src/poi.c:421
 msgid "Select POI"
 msgstr "Seleccionar pto de interés"
 
-#: ../src/maemo-mapper.c:8630
+#: ../src/poi.c:1933
+msgid ""
+"Select an operation to perform\n"
+"on the POIs that you checked\n"
+"in the POI list."
+msgstr ""
+
+#: ../src/poi.c:486
 msgid "Select one POI from the list."
 msgstr "Seleccione uno de los puntos de interés de la lista."
 
-#: ../src/maemo-mapper.c:4998
-msgid "Sensitivity"
-msgstr "Sensitividad"
+#: ../src/poi.c:142
+#, fuzzy
+msgid "Service Station"
+msgstr "Ocio"
 
-#: ../src/maemo-mapper.c:6431
+#: ../src/poi.c:1502 ../src/poi.c:1939
+#, fuzzy
+msgid "Set Category..."
+msgstr "Editar categorías..."
+
+#: ../src/cmenu.c:614
 msgid "Set as GPS Location"
 msgstr "Situar GPS"
 
-#: ../src/maemo-mapper.c:4940
+#: ../src/settings.c:980
 msgid "Settings"
 msgstr "Preferencias"
 
-#: ../src/maemo-mapper.c:6288
+#: ../src/menu.c:1592
 msgid "Settings..."
 msgstr "Preferencias..."
 
-#: ../src/maemo-mapper.c:12058
+#: ../src/maps.c:2059
 msgid "Setup"
 msgstr "Configuración"
 
-#: ../src/maemo-mapper.c:2991
+#: ../src/poi.c:148
 msgid "Shopping/Services"
 msgstr "Comercios"
 
-#: ../src/maemo-mapper.c:6442
+#: ../src/menu.c:1501
+#, fuzzy
+msgid "Show"
+msgstr "Educación"
+
+#: ../src/cmenu.c:625
 msgid "Show Description"
 msgstr "Ver descripción"
 
-#: ../src/maemo-mapper.c:6157 ../src/maemo-mapper.c:8064
+#: ../src/main.c:273 ../src/menu.c:1389
 msgid "Show Distance from Beginning"
 msgstr "Mostrar distancia desde salida"
 
-#: ../src/maemo-mapper.c:8062
+#: ../src/main.c:271
 msgid "Show Distance from Last Break"
 msgstr "Mostrar distancia desde última parada"
 
-#: ../src/maemo-mapper.c:6155
+#: ../src/menu.c:1387
 msgid "Show Distance from Last Mark"
 msgstr "Mostrar distancia desde última marca"
 
-#: ../src/maemo-mapper.c:6418 ../src/maemo-mapper.c:6449
-#: ../src/maemo-mapper.c:6473
+#: ../src/cmenu.c:601 ../src/cmenu.c:632 ../src/cmenu.c:656
 msgid "Show Distance to"
 msgstr "Mostrar distancia a"
 
-#: ../src/maemo-mapper.c:6135 ../src/maemo-mapper.c:8058
+#: ../src/main.c:267 ../src/menu.c:1367
 msgid "Show Distance to End of Route"
 msgstr "Mostrar distancia a llegada"
 
-#: ../src/maemo-mapper.c:6133 ../src/maemo-mapper.c:8056
+#: ../src/main.c:265 ../src/menu.c:1365
 msgid "Show Distance to Next Waypoint"
 msgstr "Mostrar distancia a siguiente etapa"
 
-#: ../src/maemo-mapper.c:6274
+#: ../src/menu.c:1578
 msgid "Show Information"
 msgstr "Mostrar información"
 
-#: ../src/maemo-mapper.c:6415 ../src/maemo-mapper.c:6440
+#: ../src/cmenu.c:598 ../src/cmenu.c:623
 msgid "Show Lat/Lon"
 msgstr "Mostrar Lat/Lon"
 
-#: ../src/maemo-mapper.c:5196
+#: ../src/settings.c:1283
 msgid "Show POI below zoom"
 msgstr "Ptos. de int. en zoom menores de"
 
-#: ../src/maemo-mapper.c:13414
+#: ../src/display.c:2416
 msgid "Show Position"
 msgstr "Mostrar posición"
 
-#: ../src/maemo-mapper.c:2292
+#: ../src/display.c:284
 msgid "Simulation"
 msgstr "Simulación"
 
-#: ../src/maemo-mapper.c:10049
+#: ../src/path.c:1086 ../src/poi.c:2220
 msgid "Source URL"
 msgstr "Dirección de origen"
 
-#: ../src/maemo-mapper.c:2804 ../src/maemo-mapper.c:5055
+#: ../src/menu.c:1475
+#, fuzzy
+msgid "South"
+msgstr "Desplazarse al sur"
+
+#: ../src/display.c:796
 msgid "Speed"
 msgstr "Velocidad"
 
-#: ../src/maemo-mapper.c:5152
+#: ../src/settings.c:1239
 msgid "Speed Limit"
 msgstr "Límite de velocidad"
 
-#: ../src/maemo-mapper.c:2986
+#: ../src/poi.c:143
 msgid "Stations for purchasing fuel for vehicles."
 msgstr "Estaciones de servicio para repostar gasolina."
 
-#: ../src/maemo-mapper.c:3399
+#: ../src/maps.c:504
+msgid ""
+"The current repository is in a legacy format and will be converted.  You "
+"should delete your old maps if you no longer plan to use them."
+msgstr ""
+
+#: ../src/path.c:551
 msgid "The current route is empty."
 msgstr "El itinerario actual está vacío."
 
-#: ../src/maemo-mapper.c:3445 ../src/maemo-mapper.c:3460
+#: ../src/path.c:597 ../src/path.c:612
 msgid "The current track is empty."
 msgstr "La traza actual está vacía."
 
-#: ../src/maemo-mapper.c:4660
+#: ../src/settings.c:696
 msgid "The following action is mapped to multiple keys"
 msgstr "La siguiente acción está asignada a varias teclas"
 
-#: ../src/maemo-mapper.c:9002
+#: ../src/input.c:364
 msgid "There are no other next-able repositories."
 msgstr "No hay más repositorios."
 
-#: ../src/maemo-mapper.c:13853
+#: ../src/cmenu.c:265 ../src/cmenu.c:287 ../src/cmenu.c:306 ../src/cmenu.c:326
+#: ../src/cmenu.c:345 ../src/cmenu.c:364 ../src/cmenu.c:442 ../src/cmenu.c:461
 msgid "There are no waypoints."
 msgstr "No hay etapas."
 
-#: ../src/maemo-mapper.c:3380 ../src/maemo-mapper.c:11044
+#: ../src/menu.c:912 ../src/path.c:532
 msgid "There is no next waypoint."
 msgstr "No hay una siguiente etapa."
 
-#: ../src/maemo-mapper.c:8046
+#: ../src/main.c:253
 msgid "Toggle Auto-Center"
 msgstr "Activar/desactivar autocentrado"
 
-#: ../src/maemo-mapper.c:8048
+#: ../src/main.c:255
+#, fuzzy
+msgid "Toggle Auto-Rotate"
+msgstr "Activar/desactivar autocentrado"
+
+#: ../src/main.c:257
 msgid "Toggle Fullscreen"
 msgstr "Activar/desactivar pantalla completa"
 
-#: ../src/maemo-mapper.c:8065
+#: ../src/main.c:274
 msgid "Toggle GPS"
 msgstr "Activar/desactivar GPS"
 
-#: ../src/maemo-mapper.c:8066
+#: ../src/main.c:275
 msgid "Toggle GPS Info"
 msgstr "Activar/desactivar información del GPS"
 
-#: ../src/maemo-mapper.c:8053
+#: ../src/main.c:262
 msgid "Toggle POIs"
 msgstr "Activar/desactivar puntos de interés"
 
-#: ../src/maemo-mapper.c:8052
+#: ../src/main.c:261
 msgid "Toggle Scale"
 msgstr "Activar/desactivar escala"
 
-#: ../src/maemo-mapper.c:8068
+#: ../src/main.c:277
 msgid "Toggle Speed Limit"
 msgstr "Activar/desactivar límite de velocidad"
 
-#: ../src/maemo-mapper.c:8051
+#: ../src/main.c:260
 msgid "Toggle Tracks"
 msgstr "Activar/desactivar trazas"
 
-#: ../src/maemo-mapper.c:8095 ../src/maemo-mapper.c:12186
+#: ../src/main.c:304 ../src/maps.c:2187
 msgid "Top-Left"
 msgstr "Superior izquierda"
 
-#: ../src/maemo-mapper.c:8096
+#: ../src/main.c:305
 msgid "Top-Right"
 msgstr "Superior derecha"
 
-#: ../src/maemo-mapper.c:4762 ../src/maemo-mapper.c:6143
-#: ../src/maemo-mapper.c:6209
+#: ../src/menu.c:1375 ../src/menu.c:1525 ../src/settings.c:793
 msgid "Track"
 msgstr "Traza"
 
-#: ../src/maemo-mapper.c:10434
+#: ../src/menu.c:231
 msgid "Track Opened"
 msgstr "Traza abierta"
 
-#: ../src/maemo-mapper.c:10456
+#: ../src/menu.c:253
 msgid "Track Saved"
 msgstr "Traza guardada"
 
-#: ../src/maemo-mapper.c:10655
+#: ../src/menu.c:985
 msgid "Tracks are now hidden"
 msgstr "Se han ocultado las trazas"
 
-#: ../src/maemo-mapper.c:10649
+#: ../src/menu.c:979
 msgid "Tracks are now shown"
 msgstr "Se muestran las trazas"
 
-#: ../src/maemo-mapper.c:2995
+#: ../src/poi.c:152
 msgid "Transportation"
 msgstr "Transporte"
 
-#: ../src/maemo-mapper.c:11278
+#: ../src/maps.c:1304
 msgid "URL Format"
 msgstr "Formato de la URL"
 
-#: ../src/maemo-mapper.c:5543
-msgid "Unable to create cache directory for repository"
+#: ../src/maps.c:684
+#, fuzzy
+msgid "Unable to create map database for repository"
 msgstr "No se ha podido crear el directorio de caché para el repositorio"
 
-#: ../src/maemo-mapper.c:5118
+#: ../src/settings.c:1162
+#, fuzzy
+msgid "Unblank Screen"
+msgstr "Pantalla completa"
+
+#: ../src/settings.c:1191
 msgid "Units"
 msgstr "Unidades"
 
-#: ../src/maemo-mapper.c:11003
+#: ../src/util.c:155
 msgid "Unknown error while locating address."
 msgstr "Error desconocido al localizar la dirección"
 
-#: ../src/maemo-mapper.c:10070
+#: ../src/main.c:193 ../src/menu.c:1464
+msgid "Up"
+msgstr ""
+
+#: ../src/path.c:1103 ../src/poi.c:2233 ../src/poi.c:2531
 msgid "Use End of Route"
 msgstr "Utilizar la llegada del itinerario"
 
-#: ../src/maemo-mapper.c:10060
+#: ../src/path.c:1097 ../src/poi.c:2227 ../src/poi.c:2525
 msgid "Use GPS Location"
 msgstr "Utilizar la localización GPS"
 
-#: ../src/maemo-mapper.c:6214
+#: ../src/menu.c:1530
 msgid "Velocity Vector"
 msgstr "Vector de velocidad"
 
-#: ../src/maemo-mapper.c:6181
+#: ../src/menu.c:1428
 msgid "View"
 msgstr "Ver"
 
-#: ../src/maemo-mapper.c:12167
+#: ../src/maps.c:2168
 msgid "View Center"
 msgstr "Centrar vista"
 
-#: ../src/maemo-mapper.c:11333
+#: ../src/maps.c:1361
 msgid "View Zoom Steps"
 msgstr "Ver pasos del zoom"
 
-#: ../src/maemo-mapper.c:6470
+#: ../src/cmenu.c:653
 msgid "View/Edit..."
 msgstr "Ver/editar..."
 
-#: ../src/maemo-mapper.c:12554
+#: ../src/poi.c:508
 msgid "WARNING: All POIs in that category will also be deleted!"
 msgstr ""
 "¡ATENCIÓN: Todos los puntos de interés de esa categoría también serán "
 "borrados!"
 
-#: ../src/maemo-mapper.c:6435
+#: ../src/cmenu.c:618
 msgid "Waypoint"
 msgstr "Etapa"
 
-#: ../src/maemo-mapper.c:6579
+#: ../src/menu.c:1477
+#, fuzzy
+msgid "West"
+msgstr "Reiniciar"
+
+#: ../src/display.c:1094
 msgid ""
 "You will now see a blank screen.  You can download maps using the \"Manage "
 "Maps\" menu item in the \"Maps\" menu.  Or, press OK to enable Auto-Download."
@@ -1300,71 +1572,116 @@ msgstr ""
 "\"Gestionar mapas\" del menú \"Mapas\" o bien pulse Aceptar para activar la "
 "autodescarga."
 
-#: ../src/maemo-mapper.c:12115
+#: ../src/maps.c:2116 ../src/menu.c:1434
 msgid "Zoom"
 msgstr "Zoom"
 
-#: ../src/maemo-mapper.c:6185 ../src/maemo-mapper.c:8049
+#: ../src/main.c:258 ../src/menu.c:1438
 msgid "Zoom In"
 msgstr "Acercarse"
 
-#: ../src/maemo-mapper.c:6194
+#: ../src/menu.c:1505
 msgid "Zoom Level"
 msgstr "Nivel de zoom"
 
-#: ../src/maemo-mapper.c:12121
+#: ../src/maps.c:2122
 msgid "Zoom Levels to Download: (0 = most detail)"
 msgstr "Niveles de zoom a descargar: (0 = máximo detalle)"
 
-#: ../src/maemo-mapper.c:6187 ../src/maemo-mapper.c:8050
+#: ../src/main.c:259 ../src/menu.c:1440
 msgid "Zoom Out"
 msgstr "Alejarse"
 
-#: ../src/maemo-mapper.c:8815 ../src/maemo-mapper.c:8928
-#: ../src/maemo-mapper.c:12356 ../src/maemo-mapper.c:12374
+#: ../src/input.c:103 ../src/input.c:290 ../src/menu.c:546 ../src/menu.c:564
 msgid "Zoom to Level"
 msgstr "Hacer zoom al nivel"
 
-#: ../src/maemo-mapper.c:11890 ../src/maemo-mapper.c:11897
+#: ../src/maps.c:1880 ../src/maps.c:1887
 msgid "about"
 msgstr "acerca de"
 
-#: ../src/maemo-mapper.c:2708
+#: ../src/display.c:700
 msgid "in use"
 msgstr "en uso"
 
-#: ../src/maemo-mapper.c:7999
+#: ../src/main.c:189
 msgid "km"
 msgstr "km"
 
-#: ../src/maemo-mapper.c:11810 ../src/maemo-mapper.c:11898
+#: ../src/maps.c:1791 ../src/maps.c:1888
 msgid "maps"
 msgstr "mapas"
 
-#: ../src/maemo-mapper.c:11804 ../src/maemo-mapper.c:11891
+#: ../src/maps.c:1785 ../src/maps.c:1881
 msgid "maps "
 msgstr "mapas "
 
-#: ../src/maemo-mapper.c:8000
+#: ../src/display.c:1466
+msgid "maps failed to download."
+msgstr ""
+
+#: ../src/main.c:190
 #, fuzzy
 msgid "mi."
 msgstr "mi."
 
-#: ../src/maemo-mapper.c:8001
+#: ../src/main.c:191
 #, fuzzy
 msgid "n.m."
 msgstr "m.n."
 
-#: ../src/maemo-mapper.c:2862
+#: ../src/display.c:854
 #, fuzzy
 msgid "nofix"
 msgstr "nofix"
 
-#: ../src/maemo-mapper.c:2293 ../src/maemo-mapper.c:2871
+#: ../src/display.c:285 ../src/display.c:863
 msgid "none"
 msgstr "ninguno"
 
-#: ../src/maemo-mapper.c:11810 ../src/maemo-mapper.c:11898
+#: ../src/maps.c:1791 ../src/maps.c:1888
 #, fuzzy
 msgid "up to about"
 msgstr "hasta"
+
+#~ msgid "Add"
+#~ msgstr "Añadir"
+
+#~ msgid "Delete"
+#~ msgstr "Eliminar"
+
+#~ msgid "Dining"
+#~ msgstr "Restaurantes"
+
+#~ msgid "Downloading maps"
+#~ msgstr "Descargando mapas"
+
+#~ msgid "Edit"
+#~ msgstr "Editar"
+
+#~ msgid ""
+#~ "Error in download.  Check internet connection and/or Map Repository URL "
+#~ "Format."
+#~ msgstr ""
+#~ "Error en la descarga. Compruebe la conexión a internet o el formato de la "
+#~ "dirección del repositorio."
+
+#~ msgid "Fuel"
+#~ msgstr "Gasolineras"
+
+#~ msgid "Keep Display On Only in Fullscreen Mode"
+#~ msgstr "Mantener display sólo en modo pantalla completa"
+
+#~ msgid ""
+#~ "Note: You can enter a device path\n"
+#~ "(e.g. \"/dev/rfcomm0\")."
+#~ msgstr ""
+#~ "Nota: Puede introducir una ruta a un dispositivo\n"
+#~ "(Ej.: \"/dev/rfcomm0\")."
+
+#  This word refers to Pitch as in of a person's voice.
+#~ msgid "Pitch"
+#~ msgstr "Tono"
+
+#~ msgid "Please specify a name for the POI."
+#~ msgstr "Por favor, especifique un nombre para el punto de interés."
index 1622efde2b42bd8397f0222fae6cfc70f736963c..d8c3b8a98e61170845fd7836d19a8844ba53412f 100644 (file)
@@ -11,81 +11,80 @@ msgid ""
 msgstr ""
 "Project-Id-Version: maemo-mapper 1.2.4\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-07-07 20:45-0400\n"
-"PO-Revision-Date: 2007-03-18 18:12+0200\n"
+"POT-Creation-Date: 2007-11-01 15:35-0400\n"
+"PO-Revision-Date: 2007-10-12 21:42+0200\n"
 "Last-Translator: Marko Vertainen <marko.vertainen@iki.fi>\n"
 "Language-Team: John Costigan <gnuite@gmail.com>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: ../src/maemo-mapper.c:12960
+#: ../src/poi.c:922
 msgid "# POIs"
 msgstr "# POI:t"
 
-#: ../src/maemo-mapper.c:6293
+#: ../src/menu.c:1597
 msgid "About..."
 msgstr "Tietoja..."
 
-#: ../src/maemo-mapper.c:12916
-msgid "Add"
-msgstr "Lisää"
-
-#: ../src/maemo-mapper.c:12650
+#: ../src/poi.c:604
 msgid "Add Category"
 msgstr "Lisää kategoria"
 
-#: ../src/maemo-mapper.c:13149
+#: ../src/poi.c:1123
 msgid "Add POI"
 msgstr "Lisää POI"
 
-#: ../src/maemo-mapper.c:6427 ../src/maemo-mapper.c:6456
+#: ../src/cmenu.c:610 ../src/cmenu.c:639
 msgid "Add POI..."
 msgstr "Lisää POI..."
 
-#: ../src/maemo-mapper.c:6423 ../src/maemo-mapper.c:6478
+#: ../src/cmenu.c:606 ../src/cmenu.c:661
 msgid "Add Route Point"
 msgstr "Lisää reittipiste"
 
-#: ../src/maemo-mapper.c:13601
+#: ../src/path.c:1334
 msgid "Add Waypoint"
 msgstr "Lisää kohdepiste"
 
-#: ../src/maemo-mapper.c:6425 ../src/maemo-mapper.c:6480
+#: ../src/cmenu.c:608 ../src/cmenu.c:663
 msgid "Add Waypoint..."
 msgstr "Lisää kohdepiste..."
 
-#: ../src/maemo-mapper.c:10910
+#: ../src/poi.c:878
 #, fuzzy
+msgid "Add..."
+msgstr "Lisää POI..."
+
+#: ../src/menu.c:837
 msgid "Address"
-msgstr "Lisää"
+msgstr "Osoite"
 
-#: ../src/maemo-mapper.c:10987
+#: ../src/menu.c:862
 msgid "Address Located"
-msgstr ""
+msgstr "Osoite löydetty"
 
-#: ../src/maemo-mapper.c:6256
-#, fuzzy
+#: ../src/menu.c:1489
 msgid "Address..."
-msgstr "Lisää POI..."
+msgstr "Osoitteeseen..."
 
-#: ../src/maemo-mapper.c:5029
+#: ../src/settings.c:1126
 msgid "Advance Notice"
 msgstr "Ennakkovaroitus"
 
-#: ../src/maemo-mapper.c:12100
+#: ../src/maps.c:2101
 msgid "Along Route - Radius (tiles):"
 msgstr "Reitin varrelta - Säde:"
 
-#: ../src/maemo-mapper.c:2813
+#: ../src/display.c:805
 msgid "Altitude"
 msgstr "Korkeus"
 
-#: ../src/maemo-mapper.c:4501
+#: ../src/settings.c:548
 msgid "An error occurred while attempting to scan for bluetooth devices."
 msgstr "Tapahtui virhe bluetooth laitteita haettaessa."
 
-#: ../src/maemo-mapper.c:11489
+#: ../src/maps.c:1517
 msgid ""
 "An error occurred while retrieving the repositories.  The web service may be "
 "temporarily down."
@@ -93,7 +92,7 @@ msgstr ""
 "Tapahtui virhe varastoja haettaessa. Palvelu saattaa olla väliaikaisesti "
 "pois käytöstä."
 
-#: ../src/maemo-mapper.c:8829
+#: ../src/gps.c:955
 msgid ""
 "An error occurred while trying to reset the bluetooth radio.\n"
 "\n"
@@ -105,147 +104,205 @@ msgstr ""
 "Muistitko muokata\n"
 "/etc/sudoers tiedostoa?"
 
-#: ../src/maemo-mapper.c:5025
+#: ../src/settings.c:1122
 msgid "Announce"
 msgstr "Ilmoitus"
 
-#: ../src/maemo-mapper.c:12137
+#: ../src/maps.c:2138
 msgid "Area"
 msgstr "Alue"
 
-#: ../src/maemo-mapper.c:4994 ../src/maemo-mapper.c:6227
+#: ../src/menu.c:1540 ../src/settings.c:1061
 msgid "Auto-Center"
 msgstr "Autom. keskitys"
 
-#: ../src/maemo-mapper.c:10774
+#: ../src/menu.c:1114
 msgid "Auto-Center Mode: Lat/Lon"
 msgstr "Automaattinen keskitys: Lat/Lon"
 
-#: ../src/maemo-mapper.c:10759
+#: ../src/menu.c:1097
 msgid "Auto-Center Mode: Lead"
 msgstr "Automaattinen keskitys: Etumatka"
 
-#: ../src/maemo-mapper.c:10788
+#: ../src/menu.c:1130
 msgid "Auto-Center Off"
 msgstr "Automaattinen keskitys pois päältä"
 
-#: ../src/maemo-mapper.c:6172
+#: ../src/menu.c:1419
 msgid "Auto-Download"
 msgstr "Autom. noutaminen"
 
-#: ../src/maemo-mapper.c:10064
+#: ../src/settings.c:1221
+#, fuzzy
+msgid "Auto-Download Pre-cache"
+msgstr "Autom. noutaminen"
+
+#: ../src/menu.c:1454
+#, fuzzy
+msgid "Auto-Rotate"
+msgstr "Autom. päivitys"
+
+#: ../src/menu.c:624
+msgid "Auto-Rotate Disabled"
+msgstr ""
+
+#: ../src/menu.c:619
+msgid "Auto-Rotate Enabled"
+msgstr ""
+
+#: ../src/path.c:1113
 msgid "Auto-Update"
 msgstr "Autom. päivitys"
 
-#: ../src/maemo-mapper.c:10076
+#: ../src/path.c:1119
 msgid "Avoid Highways"
-msgstr ""
+msgstr "Vältä valtateitä"
 
-#: ../src/maemo-mapper.c:8098
+#: ../src/poi.c:1749
+#, fuzzy
+msgid "Bear."
+msgstr "Tyhjennä"
+
+#: ../src/main.c:310
+#, fuzzy
+msgid "Bluetooth"
+msgstr "Nollaa bluetooth"
+
+#: ../src/main.c:307
 msgid "Bottom-Left"
 msgstr "Ala-vasen"
 
-#: ../src/maemo-mapper.c:8097 ../src/maemo-mapper.c:12208
+#: ../src/main.c:306 ../src/maps.c:2209
 msgid "Bottom-Right"
 msgstr "Ala-oikea"
 
-#: ../src/maemo-mapper.c:3767
+#: ../src/path.c:967
 msgid "Break already inserted."
 msgstr "Katkaisupiste on jo asetettu."
 
-#: ../src/maemo-mapper.c:5191 ../src/maemo-mapper.c:11297
+#: ../src/poi.c:2509
+#, fuzzy
+msgid "Browse POIs"
+msgstr "POI:t päällä/pois"
+
+#: ../src/maps.c:1323 ../src/menu.c:1403 ../src/settings.c:1054
+#: ../src/settings.c:1278
 msgid "Browse..."
 msgstr "Selaa"
 
-#: ../src/maemo-mapper.c:2996
+#: ../src/poi.c:153
 msgid "Bus stops, airports, train stations, etc."
 msgstr "Bussi- ja rautatieasemat, lentokentät ym."
 
-#: ../src/maemo-mapper.c:3001
+#: ../src/poi.c:158
 msgid "Business"
 msgstr "Liike-elämä"
 
-#: ../src/maemo-mapper.c:12091
+#: ../src/maps.c:2092
 msgid "By Area (see tab)"
 msgstr "Alueelta (katso välilehti)"
 
-#: ../src/maemo-mapper.c:11287
-msgid "Cache Dir."
+#: ../src/maps.c:1313
+#, fuzzy
+msgid "Cache DB"
 msgstr "Tallennuskansio"
 
-#: ../src/maemo-mapper.c:11227
+#: ../src/maps.c:1253
 msgid ""
 "Cannot delete the last repository - there must be at lease one repository."
 msgstr ""
 "Ei voida poistaa viimeistä varastoa - vähintään yksi varasto pitää olla "
 "määriteltynä."
 
-#: ../src/maemo-mapper.c:12416
+#: ../src/menu.c:1177
+#, fuzzy
 msgid ""
-"Cannot enable GPS until a GPS Receiver MAC is set in the Settings dialog box."
+"Cannot enable GPS until a GPS receiver is set up in the Settings dialog box."
 msgstr ""
 "GPS:ää ei voida ottaa käyttöön ennenkuin GPS:n MAC-osoite on määritelty "
 "asetusten valintaikkunassa."
 
-#: ../src/maemo-mapper.c:8597 ../src/maemo-mapper.c:13185
+#: ../src/menu.c:1405
+#, fuzzy
+msgid "Categories..."
+msgstr "POI-kategoriat..."
+
+#: ../src/poi.c:458 ../src/poi.c:1159 ../src/poi.c:1512 ../src/poi.c:1732
+#: ../src/poi.c:2089 ../src/poi.c:2243 ../src/poi.c:2540
 msgid "Category"
 msgstr "Kategoria"
 
-#: ../src/maemo-mapper.c:6139 ../src/maemo-mapper.c:6159
-#: ../src/maemo-mapper.c:12044
+#: ../src/poi.c:1928 ../src/poi.c:2003
+msgid "Checked POI Actions..."
+msgstr ""
+
+#: ../src/maps.c:2045 ../src/menu.c:1371 ../src/menu.c:1391
 msgid "Clear"
 msgstr "Tyhjennä"
 
-#: ../src/maemo-mapper.c:8060
-#, fuzzy
+#: ../src/main.c:269
 msgid "Clear Track"
-msgstr "Reittijäljet päällä/pois"
+msgstr "Tyhjennä reittijälki"
 
-#: ../src/maemo-mapper.c:6295
+#: ../src/menu.c:1448
+#, fuzzy
+msgid "Clockwise"
+msgstr "Sulje"
+
+#: ../src/menu.c:1599
 msgid "Close"
 msgstr "Sulje"
 
-#: ../src/maemo-mapper.c:4729
+#: ../src/settings.c:760
 msgid "Colors"
 msgstr "Värit"
 
-#: ../src/maemo-mapper.c:4953
+#: ../src/settings.c:993
 msgid "Colors..."
 msgstr "Värit..."
 
-#: ../src/maemo-mapper.c:11803 ../src/maemo-mapper.c:11890
+#: ../src/menu.c:1515
+msgid "Compass Rose"
+msgstr ""
+
+#: ../src/maps.c:1784 ../src/maps.c:1880
 msgid "Confirm DELETION of"
 msgstr "Vahvista"
 
-#: ../src/maemo-mapper.c:11234
+#: ../src/maps.c:1260
 msgid "Confirm delete of repository"
 msgstr "Vahvista varaston poisto"
 
-#: ../src/maemo-mapper.c:13966
+#: ../src/cmenu.c:385
 msgid "Confirm delete of waypoint"
 msgstr "Vahvista kohdepisteen poisto"
 
-#: ../src/maemo-mapper.c:11809 ../src/maemo-mapper.c:11896
+#: ../src/maps.c:1790 ../src/maps.c:1886
 msgid "Confirm download of"
 msgstr "Vahvista"
 
-#: ../src/maemo-mapper.c:4663
+#: ../src/settings.c:699
 msgid "Continue?"
 msgstr "Jatka?"
 
-#: ../src/maemo-mapper.c:13451
+#: ../src/display.c:2453
 msgid "Copy"
-msgstr ""
+msgstr "Kopioi"
 
-#: ../src/maemo-mapper.c:6446
+#: ../src/cmenu.c:629
 msgid "Copy Description"
 msgstr "Kopioi kuvaus"
 
-#: ../src/maemo-mapper.c:6444
+#: ../src/cmenu.c:627
 msgid "Copy Lat/Lon"
 msgstr "Kopioi Lat/Lon"
 
-#: ../src/maemo-mapper.c:13684
+#: ../src/menu.c:1450
+#, fuzzy
+msgid "Counter"
+msgstr "Reittisuunnitelma"
+
+#: ../src/path.c:1417
 msgid ""
 "Creating a \"waypoint\" with no description actually adds a break point.  Is "
 "that what you want?"
@@ -253,336 +310,449 @@ msgstr ""
 "Luotaessa \"kohdepiste\"  ilman kuvausta, lisää itseasiassa katkaisupisteen. "
 "Tarkoititko sitä?"
 
-#: ../src/maemo-mapper.c:2286
+#: ../src/display.c:278
 msgid "DGPS"
 msgstr "DGPS"
 
-#: ../src/maemo-mapper.c:5129
+#: ../src/poi.c:2079
+#, fuzzy
+msgid "Default Category"
+msgstr "Poista kategoria?"
+
+#: ../src/settings.c:1208
 msgid "Degrees Format"
 msgstr "Asteiden muoto"
 
-#: ../src/maemo-mapper.c:12631 ../src/maemo-mapper.c:13124
-msgid "Delete"
-msgstr "Poista"
-
-#: ../src/maemo-mapper.c:12081
+#: ../src/maps.c:2082
 msgid "Delete Maps"
 msgstr "Poista kartat"
 
-#: ../src/maemo-mapper.c:13008
+#: ../src/poi.c:958
 msgid "Delete POI?"
 msgstr "Poista POI?"
 
-#: ../src/maemo-mapper.c:12552
+#: ../src/poi.c:506
 msgid "Delete category?"
 msgstr "Poista kategoria?"
 
-#: ../src/maemo-mapper.c:6453 ../src/maemo-mapper.c:11586
+#: ../src/poi.c:1843
+#, fuzzy
+msgid "Delete selected POI?"
+msgstr "Poista POI?"
+
+#: ../src/cmenu.c:636 ../src/maps.c:1614 ../src/poi.c:585 ../src/poi.c:1096
+#: ../src/poi.c:1943
 msgid "Delete..."
 msgstr "Poista..."
 
-#: ../src/maemo-mapper.c:4489 ../src/maemo-mapper.c:10513
-#: ../src/maemo-mapper.c:12669 ../src/maemo-mapper.c:12955
-#: ../src/maemo-mapper.c:13212 ../src/maemo-mapper.c:13626
+#: ../src/menu.c:310 ../src/path.c:1359 ../src/poi.c:623 ../src/poi.c:917
+#: ../src/poi.c:1174 ../src/settings.c:536
 msgid "Description"
 msgstr "Kuvaus"
 
-#: ../src/maemo-mapper.c:10093
+#: ../src/path.c:1136
 msgid "Destination"
 msgstr "Kohdepiste"
 
-#: ../src/maemo-mapper.c:6278
+#: ../src/menu.c:1582
 msgid "Details..."
 msgstr "Yksityiskohdat..."
 
-#: ../src/maemo-mapper.c:2989
-msgid "Dining"
-msgstr "Ruokailu"
+#: ../src/gps.c:779
+#, fuzzy
+msgid "Disconnecting from GPS receiver"
+msgstr "Etsitään GPS-vastaanotinta"
+
+#: ../src/poi.c:1740
+#, fuzzy
+msgid "Dist."
+msgstr "Etäisyys"
 
-#: ../src/maemo-mapper.c:3365 ../src/maemo-mapper.c:3425
-#: ../src/maemo-mapper.c:13566
+#: ../src/cmenu.c:136 ../src/path.c:517 ../src/path.c:577
 msgid "Distance"
 msgstr "Etäisyys"
 
-#: ../src/maemo-mapper.c:11354
+#: ../src/maps.c:1382
 msgid "Double Pixels"
 msgstr "Tuplapikselit"
 
-#: ../src/maemo-mapper.c:12068
+#: ../src/main.c:195 ../src/menu.c:1466
+msgid "Down"
+msgstr ""
+
+#: ../src/maps.c:2069
 msgid "Download Maps"
 msgstr "Lataa kartat"
 
-#: ../src/maemo-mapper.c:10034
+#: ../src/poi.c:2202
+#, fuzzy
+msgid "Download POIs"
+msgstr "Lataa kartat"
+
+#: ../src/path.c:1071
 msgid "Download Route"
 msgstr "Lataa reittisuunnitelma"
 
-#: ../src/maemo-mapper.c:6420 ../src/maemo-mapper.c:6451
-#: ../src/maemo-mapper.c:6475
+#: ../src/cmenu.c:603 ../src/cmenu.c:634 ../src/cmenu.c:658
 msgid "Download Route to..."
 msgstr "Lataa reittisuunnitelma kohteeseen..."
 
-#: ../src/maemo-mapper.c:11317
+#: ../src/maps.c:1345
 msgid "Download Zoom Steps"
 msgstr "Lataa zoom tasot"
 
-#: ../src/maemo-mapper.c:6129 ../src/maemo-mapper.c:11567
+#: ../src/maps.c:1595 ../src/menu.c:1361 ../src/menu.c:1401
 msgid "Download..."
 msgstr "Lataa..."
 
-#: ../src/maemo-mapper.c:6937
-msgid "Downloading maps"
-msgstr "Ladataan karttoja"
+#: ../src/maps.c:654 ../src/maps.c:667
+msgid "Downloaded maps will not be cached."
+msgstr ""
 
-#: ../src/maemo-mapper.c:12913
-msgid "Edit"
-msgstr "Muokkaa"
+#: ../src/menu.c:1479
+#, fuzzy
+msgid "East"
+msgstr "Vieritä itään"
 
-#: ../src/maemo-mapper.c:13208
+#: ../src/poi.c:1170
 msgid "Edit Categories..."
 msgstr "Muokkaa kategorioita..."
 
-#: ../src/maemo-mapper.c:12625
+#: ../src/poi.c:579
 msgid "Edit Category"
 msgstr "Muokkaa kategoriaa"
 
-#: ../src/maemo-mapper.c:13118
+#: ../src/poi.c:1090
 msgid "Edit POI"
 msgstr "Muokkaa POI:ta"
 
-#: ../src/maemo-mapper.c:3000
+#: ../src/poi.c:875 ../src/poi.c:1999
+#, fuzzy
+msgid "Edit..."
+msgstr "Näytä/Muokkaa..."
+
+#: ../src/poi.c:157
 msgid "Elementary schools, college campuses, etc."
 msgstr "Elementary schools, college campuses, etc."
 
-#: ../src/maemo-mapper.c:6270
+#: ../src/menu.c:1574
 msgid "Enable GPS"
 msgstr "Käytä GPS:ää"
 
-#: ../src/maemo-mapper.c:5042
+#: ../src/settings.c:1139
 msgid "Enable Voice Synthesis (requires flite)"
 msgstr "Käytä puhesyntetisaattoria (vaatii flite:n)"
 
-#: ../src/maemo-mapper.c:12693 ../src/maemo-mapper.c:12945
+#: ../src/poi.c:647 ../src/poi.c:907
 msgid "Enabled"
 msgstr "Käytössä"
 
-#: ../src/maemo-mapper.c:7185
-msgid ""
-"Error in download.  Check internet connection and/or Map Repository URL "
-"Format."
+#: ../src/poi.c:1305
+#, fuzzy
+msgid "Error adding POI"
+msgstr "Ongelma POI:n lisäämisessä"
+
+#: ../src/poi.c:710
+#, fuzzy
+msgid "Error adding category"
+msgstr "Ongelma kategorian lisäämisessä"
+
+#: ../src/gps.c:631
+#, fuzzy
+msgid "Error connecting to GPS receiver."
+msgstr "Yhteys GPS vastaanottimeen epäonnistui. Yritä uudelleen?"
+
+#: ../src/gps.c:617
+msgid "Error connecting to GPSD."
 msgstr ""
-"Virhe latauksessa. Tarkista Internet yhteys ja/tai karttavaraston URL:n "
-"oikeellisuus."
 
-#: ../src/maemo-mapper.c:8371 ../src/maemo-mapper.c:10319
-#: ../src/maemo-mapper.c:10363 ../src/maemo-mapper.c:10437
+#: ../src/poi.c:521 ../src/poi.c:969 ../src/poi.c:1871
+#, fuzzy
+msgid "Error deleting POI"
+msgstr "Ongelma POI:n poistamisessa"
+
+#: ../src/poi.c:530
+#, fuzzy
+msgid "Error deleting category"
+msgstr "Ongelma kategorian poistossa"
+
+#: ../src/main.c:488 ../src/menu.c:122 ../src/menu.c:234 ../src/path.c:678
+#: ../src/poi.c:2130 ../src/poi.c:2481
 msgid "Error parsing GPX file."
 msgstr "Virhe tulkittaessa GPX tiedostoa."
 
-#: ../src/maemo-mapper.c:1501
+#: ../src/gps.c:667
+#, fuzzy
+msgid "Error reading GPS data."
+msgstr "Virhe tulkittaessa GPX tiedostoa."
+
+#: ../src/poi.c:754
+#, fuzzy
+msgid "Error updating Category"
+msgstr "Ongelma kategorian päivityksessä"
+
+#: ../src/poi.c:1285 ../src/poi.c:1583
+#, fuzzy
+msgid "Error updating POI"
+msgstr "Ongelma POI:n päivityksessä"
+
+#: ../src/poi.c:695
+#, fuzzy
+msgid "Error updating category"
+msgstr "Ongelma kategorian päivityksessä"
+
+#: ../src/gpx.c:478 ../src/gpx.c:805
 msgid "Error while writing to file"
 msgstr "Virhe kirjoitettaessa tiedostoa"
 
-#: ../src/maemo-mapper.c:10459 ../src/maemo-mapper.c:10618
+#: ../src/poi.c:103
+#, fuzzy
+msgid "Error with POI database"
+msgstr "Ongelma POI-tietokannassa"
+
+#: ../src/menu.c:153 ../src/menu.c:256 ../src/poi.c:1911
 msgid "Error writing GPX file."
 msgstr "Virhe kirjoitettaessa GPX tiedostoa."
 
-#: ../src/maemo-mapper.c:3148
+#: ../src/gps.c:801
 msgid "Establishing GPS fix"
 msgstr "Odotetaan GPS:n lukittumista"
 
-#: ../src/maemo-mapper.c:2290
+#: ../src/display.c:282
 msgid "Estimated"
 msgstr "Arvioitu"
 
-#: ../src/maemo-mapper.c:3903
-msgid "Failed to connect to GPS receiver.  Retry?"
+#: ../src/poi.c:1948
+msgid "Export to GPX..."
+msgstr ""
+
+#: ../src/gps.c:923
+#, fuzzy
+msgid "Failed to connect to Bluetooth GPS receiver."
 msgstr "Yhteys GPS vastaanottimeen epäonnistui. Yritä uudelleen?"
 
-#: ../src/maemo-mapper.c:10251 ../src/maemo-mapper.c:10957
+#: ../src/util.c:139
 msgid "Failed to connect to GPX Directions server"
 msgstr "Yhteyden muodostus GPX reittipalvelimeen epäonnistui"
 
-#: ../src/maemo-mapper.c:5577
+#: ../src/settings.c:1646
 msgid "Failed to initialize GConf.  Quitting."
 msgstr "GConf alustus epäonnistui.  Lopetetaan."
 
-#: ../src/maemo-mapper.c:4047
+#: ../src/settings.c:72
 msgid "Failed to initialize GConf.  Settings were not saved."
 msgstr "GConf alustus epäonnistui.  Asetuksia ei tallennettu."
 
-#: ../src/maemo-mapper.c:7750 ../src/maemo-mapper.c:8360
+#: ../src/display.c:2561 ../src/main.c:476
 msgid "Failed to open file for reading"
 msgstr "Tiedoston avaus lukemista varten epäonnistui"
 
-#: ../src/maemo-mapper.c:7403 ../src/maemo-mapper.c:7751
+#: ../src/display.c:2562
 msgid "Failed to open file for writing"
 msgstr "Tiedoston avaus kirjoitusta varten epäonnistui"
 
-#: ../src/maemo-mapper.c:3014
+#: ../src/maps.c:652 ../src/maps.c:666
+#, fuzzy
+msgid "Failed to open map database for repository"
+msgstr "Tietokannan avaus tai luonti epäonnistui"
+
+#: ../src/poi.c:171
 msgid "Failed to open or create database"
 msgstr "Tietokannan avaus tai luonti epäonnistui"
 
-#: ../src/maemo-mapper.c:1502
+#: ../src/path.c:1553
+msgid "Failed to open path database. Tracks and routes will not be saved."
+msgstr ""
+
+#: ../src/path.c:195 ../src/path.c:221 ../src/path.c:240
+msgid "Failed to write to path database. Tracks and routes may not be saved."
+msgstr ""
+
+#: ../src/main.c:312
+msgid "File"
+msgstr ""
+
+#: ../src/settings.c:1044
+msgid "File Path"
+msgstr ""
+
+#: ../src/gpx.c:479 ../src/gpx.c:806
 msgid "File is incomplete."
 msgstr "Tiedosto on vaillinainen."
 
-#: ../src/maemo-mapper.c:2858
+#: ../src/display.c:850
 msgid "Fix"
 msgstr "Lukitus"
 
-#: ../src/maemo-mapper.c:2867
+#: ../src/display.c:859
 msgid "Fix Quality"
 msgstr "Lukituksen laatu"
 
-#: ../src/maemo-mapper.c:2289
+#: ../src/settings.c:1093
+#, fuzzy
+msgid "Fixed"
+msgstr "Lukitus"
+
+#: ../src/display.c:281
 msgid "Float RTK"
 msgstr "Kelluva RTK"
 
-#: ../src/maemo-mapper.c:13442
-#, fuzzy
+#: ../src/display.c:2444
 msgid "Format"
-msgstr "URL:n muotoilu"
+msgstr "Muoto"
 
-#: ../src/maemo-mapper.c:2985
-msgid "Fuel"
-msgstr "Huoltoasemat"
-
-#: ../src/maemo-mapper.c:6189
+#: ../src/menu.c:1564
 msgid "Full Screen"
-msgstr "Kokoruutu"
+msgstr "Koko näyttö"
 
-#: ../src/maemo-mapper.c:4747 ../src/maemo-mapper.c:4964
-#: ../src/maemo-mapper.c:6266
+#: ../src/menu.c:1570 ../src/settings.c:778 ../src/settings.c:1004
 msgid "GPS"
 msgstr "GPS"
 
-#: ../src/maemo-mapper.c:2761
+#: ../src/display.c:753
 msgid "GPS Details"
 msgstr "GPS:n yksityiskohdat"
 
-#: ../src/maemo-mapper.c:2774
+#: ../src/display.c:766
 msgid "GPS Information"
 msgstr "GPS tieto"
 
-#: ../src/maemo-mapper.c:6258 ../src/maemo-mapper.c:12151
+#: ../src/maps.c:2152 ../src/menu.c:1491
 msgid "GPS Location"
-msgstr "GPS sijainti"
+msgstr "GPS-sijainti"
 
-#: ../src/maemo-mapper.c:3004
+#: ../src/main.c:311
+#, fuzzy
+msgid "GPSD"
+msgstr "GPS"
+
+#: ../src/settings.c:1025
+msgid "GPSD Host"
+msgstr ""
+
+#: ../src/poi.c:161
 msgid "General landmarks."
 msgstr "Yleiset maamerkit."
 
-#: ../src/maemo-mapper.c:3002
+#: ../src/poi.c:159
 msgid "General places of business."
 msgstr "Liike-elämän yleiset paikat."
 
-#: ../src/maemo-mapper.c:6250
+#: ../src/menu.c:1483 ../src/poi.c:1996
 msgid "Go to"
 msgstr "Siirry"
 
-#: ../src/maemo-mapper.c:10900
-#, fuzzy
+#: ../src/menu.c:827
 msgid "Go to Address"
-msgstr "Siirry lähimpään"
+msgstr "Siirry osoitteeseen"
 
-#: ../src/maemo-mapper.c:10806
+#: ../src/menu.c:731
 msgid "Go to Lat/Lon"
 msgstr "Siirry Lat/Lon"
 
-#: ../src/maemo-mapper.c:6483
+#: ../src/cmenu.c:666
 msgid "Go to Nearest"
 msgstr "Siirry lähimpään"
 
-#: ../src/maemo-mapper.c:6460
+#: ../src/cmenu.c:643
 msgid "Go to Next"
 msgstr "Siirry seuraavaan"
 
-#: ../src/maemo-mapper.c:4608
+#: ../src/settings.c:644
 msgid "Hardware Keys"
 msgstr "Näppäimet"
 
-#: ../src/maemo-mapper.c:4950
+#: ../src/settings.c:990
 msgid "Hardware Keys..."
 msgstr "Näppäimet..."
 
-#: ../src/maemo-mapper.c:2822
+#: ../src/display.c:814
 msgid "Heading"
 msgstr "Suunta"
 
-#: ../src/maemo-mapper.c:6291
+#: ../src/menu.c:1595
 msgid "Help..."
 msgstr "Ohje..."
 
-#: ../src/maemo-mapper.c:2988
+#: ../src/poi.c:145
 msgid "Houses, apartments, or other residences of import."
 msgstr "Talot, asunnot tai muut tärkeät asuinpaikat."
 
-#: ../src/maemo-mapper.c:12937
+#: ../src/poi.c:899
 msgid "ID"
 msgstr "ID"
 
-#: ../src/maemo-mapper.c:2994
+#: ../src/menu.c:1399
+msgid "Import..."
+msgstr ""
+
+#: ../src/poi.c:151
 msgid "Indoor or Outdoor places to have fun."
 msgstr "Sisä- tai ulkotiloja hauskanpitoon."
 
-#: ../src/maemo-mapper.c:5102
-msgid "Information Font Size"
-msgstr "Tietojen fonttikoko"
+#: ../src/settings.c:1174
+#, fuzzy
+msgid "Info Font Size"
+msgstr "Tietojen kirjasinkoko"
 
-#: ../src/maemo-mapper.c:6151
+#: ../src/menu.c:1383
 msgid "Insert Break"
 msgstr "Lisää katkaisupiste"
 
-#: ../src/maemo-mapper.c:10493
+#: ../src/menu.c:290
 msgid "Insert Mark"
 msgstr "Lisää merkki"
 
-#: ../src/maemo-mapper.c:6153
+#: ../src/menu.c:1385
 msgid "Insert Mark..."
 msgstr "Lisää merkki..."
 
-#: ../src/maemo-mapper.c:8059
+#: ../src/main.c:268
 msgid "Insert Track Break"
 msgstr "Lisää katkaisupiste reittijälkeen"
 
-#: ../src/maemo-mapper.c:12324
+#: ../src/maps.c:2342
 msgid "Invalid Bottom-Right Latitude"
 msgstr "Virheellinen ala-oikea latitudi"
 
-#: ../src/maemo-mapper.c:12331
+#: ../src/maps.c:2349
 msgid "Invalid Bottom-Right Longitude"
 msgstr "Virheellinen ala-oikea longitudi"
 
-#: ../src/maemo-mapper.c:10865 ../src/maemo-mapper.c:13267
+#: ../src/menu.c:792 ../src/poi.c:1224
 msgid "Invalid Latitude"
 msgstr "Virheellinen latitudi"
 
-#: ../src/maemo-mapper.c:10872 ../src/maemo-mapper.c:13274
+#: ../src/menu.c:799 ../src/poi.c:1231
 msgid "Invalid Longitude"
 msgstr "Virheellinen longitudi"
 
-#: ../src/maemo-mapper.c:9534 ../src/maemo-mapper.c:9545
+#: ../src/gps.c:66 ../src/gps.c:77
 msgid "Invalid NMEA input from receiver!"
 msgstr "Virheellinen NMEA syöte vastaanottimelta!"
 
-#: ../src/maemo-mapper.c:12310
+#: ../src/maps.c:2328
 msgid "Invalid Top-Left Latitude"
 msgstr "Virheellinen ylä-vasen latitudi"
 
-#: ../src/maemo-mapper.c:12317
+#: ../src/maps.c:2335
 msgid "Invalid Top-Left Longitude"
 msgstr "Virheellinen ylä-vasen longitudi"
 
-#: ../src/maemo-mapper.c:10971
-#, fuzzy
+#: ../src/util.c:150
 msgid "Invalid address."
-msgstr "Virheellinen latitudi"
+msgstr "Virheellinen osoite"
+
+#: ../src/poi.c:2460
+#, fuzzy
+msgid "Invalid origin or query."
+msgstr "Virheellinen longitudi"
 
-#: ../src/maemo-mapper.c:10264
+#: ../src/path.c:657
 msgid "Invalid source or destination."
-msgstr ""
+msgstr "Virheellinen lähde- tai kohdeosoite"
 
-#: ../src/maemo-mapper.c:6562
+#: ../src/display.c:1077
 msgid ""
 "It looks like this is your first time running Maemo Mapper.  Press OK to "
 "view the the help pages. Otherwise, press Cancel to continue."
@@ -590,82 +760,82 @@ msgstr ""
 "Näyttää siltä, että tämä on ensimmäinen kerta, kun käynnistit Maemo "
 "Mapperin. Valitse OK ohjeen avaamiseksi, tai valitse Cancel jatkaaksesi."
 
-#: ../src/maemo-mapper.c:5094
-msgid "Keep Display On Only in Fullscreen Mode"
-msgstr "Pidä näyttö päällä vain kokoruudun ollessa käytössä"
-
-#: ../src/maemo-mapper.c:8592 ../src/maemo-mapper.c:12661
-#: ../src/maemo-mapper.c:12950 ../src/maemo-mapper.c:13177
+#: ../src/poi.c:453 ../src/poi.c:615 ../src/poi.c:912 ../src/poi.c:1151
+#: ../src/poi.c:1757
 msgid "Label"
 msgstr "Nimike"
 
-#: ../src/maemo-mapper.c:3003
+#: ../src/poi.c:160
 msgid "Landmark"
 msgstr "Maamerkit"
 
-#: ../src/maemo-mapper.c:13161 ../src/maemo-mapper.c:13424
-#, fuzzy
+#: ../src/display.c:2426 ../src/poi.c:1135
 msgid "Lat"
-msgstr "Lat/Lon"
+msgstr "Lat"
 
-#: ../src/maemo-mapper.c:10503 ../src/maemo-mapper.c:13611
-#, fuzzy
+#: ../src/menu.c:300 ../src/path.c:1344
 msgid "Lat, Lon:"
-msgstr "Lat, Lon"
+msgstr "Lat, Lon:"
 
-#: ../src/maemo-mapper.c:6231
+#: ../src/menu.c:1544
 msgid "Lat/Lon"
 msgstr "Lat/Lon"
 
-#: ../src/maemo-mapper.c:6254
+#: ../src/menu.c:1487
 msgid "Lat/Lon..."
 msgstr "Lat/Lon..."
 
-#: ../src/maemo-mapper.c:2786 ../src/maemo-mapper.c:10816
-#: ../src/maemo-mapper.c:12141 ../src/maemo-mapper.c:13512
+#: ../src/cmenu.c:82 ../src/display.c:778 ../src/maps.c:2142 ../src/menu.c:741
 msgid "Latitude"
 msgstr "Latitudi"
 
-#: ../src/maemo-mapper.c:6237
+#: ../src/menu.c:1550
 msgid "Lead"
 msgstr "Etumatka"
 
-#: ../src/maemo-mapper.c:5011
+#: ../src/settings.c:1078
 msgid "Lead Amount"
 msgstr "Etumatkan määrä"
 
-#: ../src/maemo-mapper.c:5082
+#: ../src/main.c:196 ../src/menu.c:1468
+#, fuzzy
+msgid "Left"
+msgstr "Ylä-vasen"
+
+#: ../src/settings.c:1151
 msgid "Line Width"
-msgstr "Rivin leveys"
+msgstr "Viivan leveys"
 
-#: ../src/maemo-mapper.c:2831
+#: ../src/display.c:823
 msgid "Local time"
 msgstr "Paikallinen aika"
 
-#: ../src/maemo-mapper.c:5162 ../src/maemo-mapper.c:6409
-#: ../src/maemo-mapper.c:8587
+#: ../src/cmenu.c:592 ../src/poi.c:448 ../src/settings.c:1249
 msgid "Location"
 msgstr "Sijainti"
 
-#: ../src/maemo-mapper.c:2997
+#: ../src/poi.c:154
 msgid "Lodging"
 msgstr "Majapaikat"
 
-#: ../src/maemo-mapper.c:13169 ../src/maemo-mapper.c:13433
-#, fuzzy
+#: ../src/display.c:2435 ../src/poi.c:1143
 msgid "Lon"
-msgstr "Majapaikat"
+msgstr "Lon"
 
-#: ../src/maemo-mapper.c:2795 ../src/maemo-mapper.c:10829
-#: ../src/maemo-mapper.c:12145 ../src/maemo-mapper.c:13513
+#: ../src/cmenu.c:83 ../src/display.c:787 ../src/maps.c:2146 ../src/menu.c:755
 msgid "Longitude"
 msgstr "Longitudi"
 
-#: ../src/maemo-mapper.c:4484 ../src/maemo-mapper.c:4968
+#: ../src/settings.c:531
 msgid "MAC"
 msgstr "MAC"
 
-#: ../src/maemo-mapper.c:11470
+#: ../src/settings.c:1009
+#, fuzzy
+msgid "MAC Address"
+msgstr "Osoite"
+
+#: ../src/maps.c:1498
 msgid ""
 "Maemo Mapper will now download and add a list of possibly-duplicate "
 "repositories from the internet.  Continue?"
@@ -673,47 +843,47 @@ msgstr ""
 "Maemo Mapper lataa ja lisää listan karttavarastoja Internetistä. Osa "
 "karttavarastoista saattaa olla jo olemassa. Jatketaanko?"
 
-#: ../src/maemo-mapper.c:12033
+#: ../src/maps.c:2034
 msgid "Manage Maps"
 msgstr "Karttojen hallinta"
 
-#: ../src/maemo-mapper.c:6168
+#: ../src/menu.c:1415
 msgid "Manage Maps..."
 msgstr "Karttojen hallinta..."
 
-#: ../src/maemo-mapper.c:11550
+#: ../src/maps.c:1578
 msgid "Manage Repositories"
 msgstr "Karttavarastojen hallinta"
 
-#: ../src/maemo-mapper.c:6170
+#: ../src/menu.c:1417
 msgid "Manage Repositories..."
 msgstr "Karttavarastojen hallinta..."
 
-#: ../src/maemo-mapper.c:2291
+#: ../src/display.c:283
 msgid "Manual"
 msgstr "Manuaalinen"
 
-#: ../src/maemo-mapper.c:6163
+#: ../src/menu.c:1410
 msgid "Maps"
 msgstr "Kartat"
 
-#: ../src/maemo-mapper.c:2876
+#: ../src/display.c:868
 msgid "Max speed"
 msgstr "Maks. nopeus"
 
-#: ../src/maemo-mapper.c:5078
+#: ../src/settings.c:1147
 msgid "Misc."
 msgstr "Sekal."
 
-#: ../src/maemo-mapper.c:5114
+#: ../src/settings.c:1204
 msgid "Misc. 2"
 msgstr "Sekal. 2"
 
-#: ../src/maemo-mapper.c:3006
+#: ../src/poi.c:163
 msgid "Miscellaneous category for everything else."
 msgstr "Sekalainen kategoria kaikelle muulle."
 
-#: ../src/maemo-mapper.c:12285 ../src/maemo-mapper.c:12449
+#: ../src/maps.c:2294 ../src/menu.c:520
 msgid ""
 "NOTE: You must set a Map URI in the current repository in order to download "
 "maps."
@@ -721,63 +891,66 @@ msgstr ""
 "HUOM: Karttojen URI täytyy asettaa karttavarastojen hallinnassa, jotta "
 "kartat voidaan ladata."
 
-#: ../src/maemo-mapper.c:11171 ../src/maemo-mapper.c:11409
+#: ../src/maps.c:1197 ../src/maps.c:1437
 msgid "Name"
 msgstr "Nimi"
 
-#: ../src/maemo-mapper.c:6262
+#: ../src/menu.c:1495
 msgid "Nearest POI"
 msgstr "Lähin POI"
 
-#: ../src/maemo-mapper.c:11161
+#: ../src/maps.c:1187
 msgid "New Name"
 msgstr "Uusi nimi"
 
-#: ../src/maemo-mapper.c:11399
+#: ../src/maps.c:1427
 msgid "New Repository"
 msgstr "Uusi karttavarasto"
 
-#: ../src/maemo-mapper.c:11589
+#: ../src/maps.c:1617
 msgid "New..."
 msgstr "Uusi..."
 
-#: ../src/maemo-mapper.c:6260
+#: ../src/menu.c:1493
 msgid "Next Waypoint"
 msgstr "Seuraava kohdepiste"
 
-#: ../src/maemo-mapper.c:11362
+#: ../src/maps.c:1390
 msgid "Next-able"
 msgstr "Pikavalittava"
 
-#: ../src/maemo-mapper.c:5283
+#: ../src/settings.c:1472
+#, fuzzy
 msgid ""
-"No GPS Receiver MAC provided.\n"
+"No GPS Receiver provided.\n"
 "GPS will be disabled."
 msgstr ""
 "GPS:n MAC-osoitetta ei ole määritelty.\n"
 "GPS ei ole käytettävissä."
 
-#: ../src/maemo-mapper.c:8530 ../src/maemo-mapper.c:11082
+#: ../src/menu.c:950 ../src/poi.c:391 ../src/poi.c:2772
 msgid "No POIs found."
 msgstr "POI:ta ei löytynyt."
 
-#: ../src/maemo-mapper.c:6243
+#: ../src/poi.c:1401
+#, fuzzy
+msgid "No POIs were found."
+msgstr "POI:ta ei löytynyt."
+
+#: ../src/main.c:309 ../src/menu.c:1556
 msgid "None"
 msgstr "Ei keskitystä"
 
-#: ../src/maemo-mapper.c:4984
-msgid ""
-"Note: You can enter a device path\n"
-"(e.g. \"/dev/rfcomm0\")."
-msgstr ""
-"Huom: Voit syöttää laitteen polun\n"
-"(esim. \"/dev/rfcomm0\")."
+#: ../src/menu.c:1473
+#, fuzzy
+msgid "North"
+msgstr "Vieritä pohjoiseen"
 
-#: ../src/maemo-mapper.c:6127 ../src/maemo-mapper.c:6147
+#: ../src/menu.c:1359 ../src/menu.c:1379
 msgid "Open..."
 msgstr "Avaa..."
 
-#: ../src/maemo-mapper.c:6572
+#: ../src/display.c:1087
 msgid ""
 "OpenStreetMap.org provides public, free-to-use maps.  You can also download "
 "a sample set of repositories from  the internet by using the \"Download...\" "
@@ -787,511 +960,599 @@ msgstr ""
 "karttoja. Voit ladata lisäksi otoksen muita karttavarastoja Internetistä "
 "\"Lataa...\" painikkeella."
 
-#: ../src/maemo-mapper.c:10083
+#: ../src/path.c:1126 ../src/poi.c:2268 ../src/poi.c:2565
 msgid "Origin"
 msgstr "Lähtöpiste"
 
-#: ../src/maemo-mapper.c:3005
+#: ../src/poi.c:162
 msgid "Other"
 msgstr "Muut"
 
-#: ../src/maemo-mapper.c:12075
+#: ../src/maps.c:2076
 msgid "Overwrite"
 msgstr "Ylikirjoita"
 
-#: ../src/maemo-mapper.c:4792 ../src/maemo-mapper.c:5177
-#: ../src/maemo-mapper.c:6464
+#: ../src/cmenu.c:647 ../src/menu.c:1395 ../src/menu.c:1534
+#: ../src/settings.c:823 ../src/settings.c:1264
 msgid "POI"
 msgstr "POI"
 
-#: ../src/maemo-mapper.c:12903
+#: ../src/poi.c:865
 msgid "POI Categories"
-msgstr "POI kategoriat"
+msgstr "POI-kategoriat"
 
-#: ../src/maemo-mapper.c:6222
-msgid "POI Categories..."
-msgstr "POI kategoriat..."
+#: ../src/poi.c:1987
+#, fuzzy
+msgid "POI List"
+msgstr "POI:t"
 
-#: ../src/maemo-mapper.c:5181
+#: ../src/settings.c:1268
 msgid "POI database"
 msgstr "POI tietokanta"
 
-#: ../src/maemo-mapper.c:6218
-msgid "POIs"
-msgstr "POI:t"
+#: ../src/poi.c:1907
+msgid "POIs Exported"
+msgstr ""
+
+#: ../src/poi.c:1395
+msgid ""
+"POIs were added to the POI database.  The following screen will allow you to "
+"modify or delete any of the new POIs."
+msgstr ""
 
-#: ../src/maemo-mapper.c:2287
+#: ../src/display.c:279
 msgid "PPS"
 msgstr "PPS"
 
-#: ../src/maemo-mapper.c:8044
+#: ../src/poi.c:2252
+msgid "Page"
+msgstr ""
+
+#: ../src/menu.c:1460
+msgid "Pan"
+msgstr ""
+
+#: ../src/main.c:245
 msgid "Pan East"
 msgstr "Vieritä itään"
 
-#: ../src/maemo-mapper.c:8041
+#: ../src/main.c:242
 msgid "Pan North"
 msgstr "Vieritä pohjoiseen"
 
-#: ../src/maemo-mapper.c:8043
+#: ../src/settings.c:1065
+#, fuzzy
+msgid "Pan Sensitivity"
+msgstr "Herkkyys"
+
+#: ../src/main.c:244
 msgid "Pan South"
 msgstr "Vieritä etelään"
 
-#: ../src/maemo-mapper.c:8042
+#: ../src/main.c:243
 msgid "Pan West"
 msgstr "Vieritä länteen"
 
-#  This word refers to Pitch as in of a person's voice.
-#: ../src/maemo-mapper.c:5067
-msgid "Pitch"
-msgstr "Korkeus"
-
-#: ../src/maemo-mapper.c:2990
+#: ../src/poi.c:147
 msgid "Places to eat or drink."
 msgstr "Baarit ja ruokailupaikat."
 
-#: ../src/maemo-mapper.c:2992
+#: ../src/poi.c:149
 msgid "Places to shop or acquire services."
 msgstr "Kauppat ja palvelut."
 
-#: ../src/maemo-mapper.c:2998
+#: ../src/poi.c:155
 msgid "Places to stay temporarily or for the night."
 msgstr "Paikat väliaikaiseen yöpymiseen."
 
-#: ../src/maemo-mapper.c:10567
+#: ../src/menu.c:364
 msgid "Please provide a description for the mark."
 msgstr "Anna merkille kuvaus."
 
-#: ../src/maemo-mapper.c:4519
+#: ../src/settings.c:566
 msgid "Please select a bluetooth device from the list."
 msgstr "Valitse bluetooth laite listalta."
 
-#: ../src/maemo-mapper.c:13289
-msgid "Please specify a category for the POI."
+#: ../src/poi.c:1250 ../src/poi.c:1532
+#, fuzzy
+msgid "Please specify a category."
 msgstr "Määrittele POI pisteen kategoria."
 
-#: ../src/maemo-mapper.c:13282
-msgid "Please specify a name for the POI."
-msgstr "Määrittele POI pisteen nimi."
+#: ../src/poi.c:2104 ../src/poi.c:2425
+#, fuzzy
+msgid "Please specify a default category."
+msgstr "Määrittele kategorian nimi."
 
-#: ../src/maemo-mapper.c:12719
+#: ../src/poi.c:673
 msgid "Please specify a name for the category."
 msgstr "Määrittele kategorian nimi."
 
-#: ../src/maemo-mapper.c:10173
+#: ../src/poi.c:1243
+#, fuzzy
+msgid "Please specify a name."
+msgstr "Määritä osoite"
+
+#: ../src/poi.c:2432
+#, fuzzy
+msgid "Please specify a query."
+msgstr "Määrittele lähde URL."
+
+#: ../src/path.c:1214 ../src/poi.c:2368
 msgid "Please specify a source URL."
 msgstr "Määrittele lähde URL."
 
-#: ../src/maemo-mapper.c:10217
+#: ../src/path.c:1256
 msgid "Please specify a start location."
 msgstr "Määrittele lähtöpiste."
 
-#: ../src/maemo-mapper.c:10941
-#, fuzzy
-msgid "Please specify an address."
-msgstr "Määrittele lähde URL."
-
-#: ../src/maemo-mapper.c:10224
+#: ../src/path.c:1263
 msgid "Please specify an end location."
 msgstr "Määrittele kohdepiste."
 
-#: ../src/maemo-mapper.c:13340
-msgid "Problem adding POI"
-msgstr "Ongelma POI:n lisäämisessä"
-
-#: ../src/maemo-mapper.c:12756
-msgid "Problem adding category"
-msgstr "Ongelma kategorian lisäämisessä"
-
-#: ../src/maemo-mapper.c:12567 ../src/maemo-mapper.c:13019
-msgid "Problem deleting POI"
-msgstr "Ongelma POI:n poistamisessa"
-
-#: ../src/maemo-mapper.c:12576
-msgid "Problem deleting category"
-msgstr "Ongelma kategorian poistossa"
+#: ../src/poi.c:2419 ../src/poi.c:2696
+#, fuzzy
+msgid "Please specify an origin."
+msgstr "Määrittele kohdepiste."
 
-#: ../src/maemo-mapper.c:12795
-msgid "Problem updating Category"
-msgstr "Ongelma kategorian päivityksessä"
+#: ../src/settings.c:1110
+msgid "Points"
+msgstr ""
 
-#: ../src/maemo-mapper.c:13318
-msgid "Problem updating POI"
-msgstr "Ongelma POI:n päivityksessä"
+#: ../src/settings.c:1035
+#, fuzzy
+msgid "Port"
+msgstr "Vieritä pohjoiseen"
 
-#: ../src/maemo-mapper.c:12741
-msgid "Problem updating category"
-msgstr "Ongelma kategorian päivityksessä"
+#: ../src/maps.c:850
+msgid "Processing Maps"
+msgstr ""
 
-#: ../src/maemo-mapper.c:2946
-msgid "Problem with POI database"
-msgstr "Ongelma POI tietokannassa"
+#: ../src/poi.c:2278 ../src/poi.c:2575
+msgid "Query"
+msgstr ""
 
-#: ../src/maemo-mapper.c:2288
+#: ../src/display.c:280
 msgid "Real Time Kinematic"
-msgstr ""
+msgstr "Real Time Kinematic"
 
-#: ../src/maemo-mapper.c:3723
+#: ../src/path.c:919
 msgid "Really clear the track?"
-msgstr ""
+msgstr "Haluatko varmasti tyhjentää reittijäljen?"
 
-#: ../src/maemo-mapper.c:3678
+#: ../src/path.c:798
 msgid "Recalculating directions..."
 msgstr "Lasketaan uusi reittisuunnitelma..."
 
-#: ../src/maemo-mapper.c:2993
+#: ../src/poi.c:150
 msgid "Recreation"
 msgstr "Virkistäytyminen"
 
-#: ../src/maemo-mapper.c:11583
+#: ../src/maps.c:1611
 msgid "Rename..."
 msgstr "Nimeä uud..."
 
-#: ../src/maemo-mapper.c:11440
+#: ../src/maps.c:1468
 msgid "Replace all repositories with the default repository?"
 msgstr "Korvaa kaikki karttavarastot oletusvarastolla?"
 
-#: ../src/maemo-mapper.c:6137
+#: ../src/menu.c:1369 ../src/menu.c:1452
 msgid "Reset"
 msgstr "Nollaa"
 
-#: ../src/maemo-mapper.c:6281 ../src/maemo-mapper.c:8069
+#: ../src/main.c:278 ../src/menu.c:1585
 msgid "Reset Bluetooth"
 msgstr "Nollaa bluetooth"
 
-#: ../src/maemo-mapper.c:4699
+#: ../src/main.c:247
+msgid "Reset Viewing Angle"
+msgstr ""
+
+#: ../src/settings.c:730
 msgid "Reset all colors to their original defaults?"
 msgstr "Korvaa kaikki värit oletusväreillä?"
 
-#: ../src/maemo-mapper.c:4580
+#: ../src/settings.c:616
 msgid "Reset all hardware keys to their original defaults?"
 msgstr "Korvaa kaikki näppäinvalinnat oletusasetuksilla?"
 
-#: ../src/maemo-mapper.c:4614 ../src/maemo-mapper.c:4735
-#: ../src/maemo-mapper.c:11561
+#: ../src/maps.c:1589 ../src/settings.c:650 ../src/settings.c:766
 msgid "Reset..."
 msgstr "Nollaa..."
 
-#: ../src/maemo-mapper.c:2987
+#: ../src/poi.c:144
 msgid "Residence"
 msgstr "Asuminen"
 
-#: ../src/maemo-mapper.c:4777 ../src/maemo-mapper.c:6123
-#: ../src/maemo-mapper.c:6204
+#: ../src/poi.c:146
+msgid "Restaurant"
+msgstr ""
+
+#: ../src/main.c:194 ../src/menu.c:1470
+#, fuzzy
+msgid "Right"
+msgstr "Ylä-oikea"
+
+#: ../src/menu.c:1444
+#, fuzzy
+msgid "Rotate"
+msgstr "Reittisuunnitelma"
+
+#: ../src/settings.c:1097
+#, fuzzy
+msgid "Rotate Sensit."
+msgstr "Herkkyys"
+
+#: ../src/main.c:249
+msgid "Rotate View Clockwise"
+msgstr ""
+
+#: ../src/main.c:251
+msgid "Rotate View Counter-Clockwise"
+msgstr ""
+
+#: ../src/menu.c:1355 ../src/menu.c:1520 ../src/settings.c:808
 msgid "Route"
 msgstr "Reittisuunnitelma"
 
-#: ../src/maemo-mapper.c:10311
+#: ../src/path.c:672
 msgid "Route Downloaded"
 msgstr "Reittisuunnitelma ladattu"
 
-#: ../src/maemo-mapper.c:8368 ../src/maemo-mapper.c:10360
+#: ../src/main.c:485 ../src/menu.c:119
 msgid "Route Opened"
 msgstr "Reittisuunnitelma avattu"
 
-#: ../src/maemo-mapper.c:10615
+#: ../src/menu.c:150
 msgid "Route Saved"
 msgstr "Reittisuunnitelma tallennettu"
 
-#: ../src/maemo-mapper.c:10705
+#: ../src/menu.c:1048
 msgid "Routes are now hidden"
 msgstr "Reitit on nyt piilotettu"
 
-#: ../src/maemo-mapper.c:10699
+#: ../src/menu.c:1042
 msgid "Routes are now shown"
 msgstr "Reitit on nyt näkyvissä"
 
-#: ../src/maemo-mapper.c:2285
+#: ../src/display.c:277
 msgid "SPS"
 msgstr "SPS"
 
-#: ../src/maemo-mapper.c:2849
+#: ../src/display.c:841
 msgid "Sat in use"
 msgstr "Sat käytössä"
 
-#: ../src/maemo-mapper.c:2840
+#: ../src/display.c:832
 msgid "Sat in view"
 msgstr "Sat näkyy"
 
-#: ../src/maemo-mapper.c:2781
+#: ../src/display.c:773
 msgid "Satellites details"
 msgstr "Satelliittien yksityiskohdat"
 
-#: ../src/maemo-mapper.c:2707
+#: ../src/display.c:699
 msgid "Satellites in view"
 msgstr "Satelliitteja näkyvissä"
 
-#: ../src/maemo-mapper.c:6131 ../src/maemo-mapper.c:6149
+#: ../src/menu.c:1363 ../src/menu.c:1381
 msgid "Save..."
 msgstr "Tallenna..."
 
-#: ../src/maemo-mapper.c:6199
+#: ../src/menu.c:1510
 msgid "Scale"
 msgstr "Asteikko"
 
-#: ../src/maemo-mapper.c:4978
+#: ../src/settings.c:1019
 msgid "Scan..."
 msgstr "Etsi..."
 
-#: ../src/maemo-mapper.c:4495
+#: ../src/settings.c:542
 msgid "Scanning for Bluetooth Devices"
 msgstr "Etsitään bluetooth laitteita"
 
-#: ../src/maemo-mapper.c:2999
+#: ../src/poi.c:156
 msgid "School"
 msgstr "Koulut"
 
-#: ../src/maemo-mapper.c:3138
+#: ../src/gps.c:790
 msgid "Searching for GPS receiver"
 msgstr "Etsitään GPS-vastaanotinta"
 
-#: ../src/maemo-mapper.c:4459
+#: ../src/settings.c:506
 msgid "Select Bluetooth Device"
 msgstr "Valitse bluetooth laite"
 
-#: ../src/maemo-mapper.c:8054
+#: ../src/main.c:263
 msgid "Select Next Repository"
 msgstr "Valitse seuraava karttavarasto"
 
-#: ../src/maemo-mapper.c:8560
+#: ../src/poi.c:421
 msgid "Select POI"
 msgstr "Valitse POI"
 
-#: ../src/maemo-mapper.c:8630
+#: ../src/poi.c:1933
+msgid ""
+"Select an operation to perform\n"
+"on the POIs that you checked\n"
+"in the POI list."
+msgstr ""
+
+#: ../src/poi.c:486
 msgid "Select one POI from the list."
 msgstr "Valitse yksi POI listalta."
 
-#: ../src/maemo-mapper.c:4998
-msgid "Sensitivity"
-msgstr "Herkkyys"
+#: ../src/poi.c:142
+#, fuzzy
+msgid "Service Station"
+msgstr "Virkistäytyminen"
+
+#: ../src/poi.c:1502 ../src/poi.c:1939
+#, fuzzy
+msgid "Set Category..."
+msgstr "Muokkaa kategorioita..."
 
-#: ../src/maemo-mapper.c:6431
+#: ../src/cmenu.c:614
 msgid "Set as GPS Location"
-msgstr "Aseta GPS sijainniksi"
+msgstr "Aseta GPS-sijainniksi"
 
-#: ../src/maemo-mapper.c:4940
+#: ../src/settings.c:980
 msgid "Settings"
 msgstr "Asetukset"
 
-#: ../src/maemo-mapper.c:6288
+#: ../src/menu.c:1592
 msgid "Settings..."
 msgstr "Asetukset..."
 
-#: ../src/maemo-mapper.c:12058
+#: ../src/maps.c:2059
 msgid "Setup"
-msgstr "Asetus"
+msgstr "Valinnat"
 
-#: ../src/maemo-mapper.c:2991
+#: ../src/poi.c:148
 msgid "Shopping/Services"
 msgstr "Kaupat/Palvelut"
 
-#: ../src/maemo-mapper.c:6442
+#: ../src/menu.c:1501
+#, fuzzy
+msgid "Show"
+msgstr "Koulut"
+
+#: ../src/cmenu.c:625
 msgid "Show Description"
 msgstr "Näytä kuvaus"
 
-#: ../src/maemo-mapper.c:6157 ../src/maemo-mapper.c:8064
+#: ../src/main.c:273 ../src/menu.c:1389
 msgid "Show Distance from Beginning"
 msgstr "Näytä etäisyys lähtöpisteestä"
 
-#: ../src/maemo-mapper.c:8062
+#: ../src/main.c:271
 msgid "Show Distance from Last Break"
-msgstr "Näytä etäisyys edellisestä katkaisupisteestä"
+msgstr "Näytä etäisyys katkaisupisteestä"
 
-#: ../src/maemo-mapper.c:6155
+#: ../src/menu.c:1387
 msgid "Show Distance from Last Mark"
 msgstr "Näytä etäisyys edellisestä merkistä"
 
-#: ../src/maemo-mapper.c:6418 ../src/maemo-mapper.c:6449
-#: ../src/maemo-mapper.c:6473
+#: ../src/cmenu.c:601 ../src/cmenu.c:632 ../src/cmenu.c:656
 msgid "Show Distance to"
 msgstr "Näytä etäisyys kohteeseen"
 
-#: ../src/maemo-mapper.c:6135 ../src/maemo-mapper.c:8058
+#: ../src/main.c:267 ../src/menu.c:1367
 msgid "Show Distance to End of Route"
 msgstr "Näytä etäisyys reitin loppupisteeseen"
 
-#: ../src/maemo-mapper.c:6133 ../src/maemo-mapper.c:8056
+#: ../src/main.c:265 ../src/menu.c:1365
 msgid "Show Distance to Next Waypoint"
-msgstr "Näytä etäisyys seuraavaan kohdepisteeseen"
+msgstr "Näytä etäisyys seur. kohdepisteeseen"
 
-#: ../src/maemo-mapper.c:6274
+#: ../src/menu.c:1578
 msgid "Show Information"
 msgstr "Näytä tietoja"
 
-#: ../src/maemo-mapper.c:6415 ../src/maemo-mapper.c:6440
+#: ../src/cmenu.c:598 ../src/cmenu.c:623
 msgid "Show Lat/Lon"
 msgstr "Näytä Lat/Lon"
 
-#: ../src/maemo-mapper.c:5196
+#: ../src/settings.c:1283
 msgid "Show POI below zoom"
 msgstr "Näytä POI:t alle zoom tason"
 
-#: ../src/maemo-mapper.c:13414
-#, fuzzy
+#: ../src/display.c:2416
 msgid "Show Position"
-msgstr "Näytä kuvaus"
+msgstr "Näytä sijainti"
 
-#: ../src/maemo-mapper.c:2292
+#: ../src/display.c:284
 msgid "Simulation"
 msgstr "Simulaatio"
 
-#: ../src/maemo-mapper.c:10049
+#: ../src/path.c:1086 ../src/poi.c:2220
 msgid "Source URL"
 msgstr "Lähde URL"
 
-#: ../src/maemo-mapper.c:2804 ../src/maemo-mapper.c:5055
+#: ../src/menu.c:1475
+#, fuzzy
+msgid "South"
+msgstr "Vieritä etelään"
+
+#: ../src/display.c:796
 msgid "Speed"
 msgstr "Nopeus"
 
-#: ../src/maemo-mapper.c:5152
+#: ../src/settings.c:1239
 msgid "Speed Limit"
 msgstr "Nopeusrajoitus"
 
-#: ../src/maemo-mapper.c:2986
+#: ../src/poi.c:143
 msgid "Stations for purchasing fuel for vehicles."
 msgstr "Huoltoasemat ja autokorjaamot."
 
-#: ../src/maemo-mapper.c:3399
+#: ../src/maps.c:504
+msgid ""
+"The current repository is in a legacy format and will be converted.  You "
+"should delete your old maps if you no longer plan to use them."
+msgstr ""
+
+#: ../src/path.c:551
 msgid "The current route is empty."
 msgstr "Nykyinen reittisuunnitelma on tyhjä."
 
-#: ../src/maemo-mapper.c:3445 ../src/maemo-mapper.c:3460
+#: ../src/path.c:597 ../src/path.c:612
 msgid "The current track is empty."
 msgstr "Nykyinen reittijälki on tyhjä."
 
-#: ../src/maemo-mapper.c:4660
+#: ../src/settings.c:696
 msgid "The following action is mapped to multiple keys"
 msgstr "Seuraava toiminne on valittu useaan näppäimeen"
 
-#: ../src/maemo-mapper.c:9002
+#: ../src/input.c:364
 msgid "There are no other next-able repositories."
 msgstr "Toista pikavalittavaa karttavarastoa ei ole määritetty."
 
-#: ../src/maemo-mapper.c:13853
+#: ../src/cmenu.c:265 ../src/cmenu.c:287 ../src/cmenu.c:306 ../src/cmenu.c:326
+#: ../src/cmenu.c:345 ../src/cmenu.c:364 ../src/cmenu.c:442 ../src/cmenu.c:461
 msgid "There are no waypoints."
 msgstr "Kohdepiste puuttuu."
 
-#: ../src/maemo-mapper.c:3380 ../src/maemo-mapper.c:11044
+#: ../src/menu.c:912 ../src/path.c:532
 msgid "There is no next waypoint."
 msgstr "Seuraava kohdepiste puuttuu."
 
-#: ../src/maemo-mapper.c:8046
+#: ../src/main.c:253
 msgid "Toggle Auto-Center"
 msgstr "Automaattinen keskitys päällä/pois"
 
-#: ../src/maemo-mapper.c:8048
+#: ../src/main.c:255
+#, fuzzy
+msgid "Toggle Auto-Rotate"
+msgstr "Automaattinen keskitys päällä/pois"
+
+#: ../src/main.c:257
 msgid "Toggle Fullscreen"
-msgstr "Kokoruutu päällä/pois"
+msgstr "Koko näyttö päällä/pois"
 
-#: ../src/maemo-mapper.c:8065
+#: ../src/main.c:274
 msgid "Toggle GPS"
 msgstr "GPS päällä/pois"
 
-#: ../src/maemo-mapper.c:8066
+#: ../src/main.c:275
 msgid "Toggle GPS Info"
 msgstr "GPS-info päällä/pois"
 
-#: ../src/maemo-mapper.c:8053
+#: ../src/main.c:262
 msgid "Toggle POIs"
 msgstr "POI:t päällä/pois"
 
-#: ../src/maemo-mapper.c:8052
+#: ../src/main.c:261
 msgid "Toggle Scale"
 msgstr "Asteikko päällä/pois"
 
-#: ../src/maemo-mapper.c:8068
+#: ../src/main.c:277
 msgid "Toggle Speed Limit"
 msgstr "Nopeusrajoitus päällä/pois"
 
-#: ../src/maemo-mapper.c:8051
+#: ../src/main.c:260
 msgid "Toggle Tracks"
 msgstr "Reittijäljet päällä/pois"
 
-#: ../src/maemo-mapper.c:8095 ../src/maemo-mapper.c:12186
+#: ../src/main.c:304 ../src/maps.c:2187
 msgid "Top-Left"
 msgstr "Ylä-vasen"
 
-#: ../src/maemo-mapper.c:8096
+#: ../src/main.c:305
 msgid "Top-Right"
 msgstr "Ylä-oikea"
 
-#: ../src/maemo-mapper.c:4762 ../src/maemo-mapper.c:6143
-#: ../src/maemo-mapper.c:6209
+#: ../src/menu.c:1375 ../src/menu.c:1525 ../src/settings.c:793
 msgid "Track"
 msgstr "Reittijälki"
 
-#: ../src/maemo-mapper.c:10434
+#: ../src/menu.c:231
 msgid "Track Opened"
 msgstr "Reittijälki avattu"
 
-#: ../src/maemo-mapper.c:10456
+#: ../src/menu.c:253
 msgid "Track Saved"
 msgstr "Reittijälki tallennettu"
 
-#: ../src/maemo-mapper.c:10655
+#: ../src/menu.c:985
 msgid "Tracks are now hidden"
 msgstr "Reittijäljet on nyt piilotettu"
 
-#: ../src/maemo-mapper.c:10649
+#: ../src/menu.c:979
 msgid "Tracks are now shown"
 msgstr "Reittijäljet on nyt nähtävissä"
 
-#: ../src/maemo-mapper.c:2995
+#: ../src/poi.c:152
 msgid "Transportation"
 msgstr "Julkinenliikenne"
 
-#: ../src/maemo-mapper.c:11278
+#: ../src/maps.c:1304
 msgid "URL Format"
 msgstr "URL:n muotoilu"
 
-#: ../src/maemo-mapper.c:5543
-msgid "Unable to create cache directory for repository"
+#: ../src/maps.c:684
+#, fuzzy
+msgid "Unable to create map database for repository"
 msgstr "Ei voitu luoda tallennuskansiota karttavarastolle"
 
-#: ../src/maemo-mapper.c:5118
+#: ../src/settings.c:1162
+#, fuzzy
+msgid "Unblank Screen"
+msgstr "Koko näyttö"
+
+#: ../src/settings.c:1191
 msgid "Units"
 msgstr "Yksiköt"
 
-#: ../src/maemo-mapper.c:11003
+#: ../src/util.c:155
 msgid "Unknown error while locating address."
+msgstr "Tunnistamaton virhe osoitteen etsinnässä."
+
+#: ../src/main.c:193 ../src/menu.c:1464
+msgid "Up"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10070
+#: ../src/path.c:1103 ../src/poi.c:2233 ../src/poi.c:2531
 msgid "Use End of Route"
 msgstr "Käytä reitin loppupistettä"
 
-#: ../src/maemo-mapper.c:10060
+#: ../src/path.c:1097 ../src/poi.c:2227 ../src/poi.c:2525
 msgid "Use GPS Location"
-msgstr "Käytä GPS sijaintia"
+msgstr "Käytä GPS-sijaintia"
 
-#: ../src/maemo-mapper.c:6214
+#: ../src/menu.c:1530
 msgid "Velocity Vector"
 msgstr "Nopeusvektori"
 
-#: ../src/maemo-mapper.c:6181
+#: ../src/menu.c:1428
 msgid "View"
 msgstr "Näytä"
 
-#: ../src/maemo-mapper.c:12167
+#: ../src/maps.c:2168
 msgid "View Center"
 msgstr "Näytä keskusta"
 
-#: ../src/maemo-mapper.c:11333
+#: ../src/maps.c:1361
 msgid "View Zoom Steps"
 msgstr "Näytä zoom tasot"
 
-#: ../src/maemo-mapper.c:6470
+#: ../src/cmenu.c:653
 msgid "View/Edit..."
 msgstr "Näytä/Muokkaa..."
 
-#: ../src/maemo-mapper.c:12554
+#: ../src/poi.c:508
 msgid "WARNING: All POIs in that category will also be deleted!"
 msgstr "VAROITUS: Kaikki POI:t tässä kategoriassa poistetaan!"
 
-#: ../src/maemo-mapper.c:6435
+#: ../src/cmenu.c:618
 msgid "Waypoint"
 msgstr "Kohdepiste"
 
-#: ../src/maemo-mapper.c:6579
+#: ../src/menu.c:1477
+#, fuzzy
+msgid "West"
+msgstr "Nollaa"
+
+#: ../src/display.c:1094
 msgid ""
 "You will now see a blank screen.  You can download maps using the \"Manage "
 "Maps\" menu item in the \"Maps\" menu.  Or, press OK to enable Auto-Download."
@@ -1300,72 +1561,77 @@ msgstr ""
 "hallinta\" valikkoa \"Kartat\" valikosta tai valitsemalla OK, jolloin "
 "automaattinen karttojen lataus otetaan käyttöön."
 
-#: ../src/maemo-mapper.c:12115
+#: ../src/maps.c:2116 ../src/menu.c:1434
 msgid "Zoom"
-msgstr "Zoomaa"
+msgstr "Zoom tasot"
 
-#: ../src/maemo-mapper.c:6185 ../src/maemo-mapper.c:8049
+#: ../src/main.c:258 ../src/menu.c:1438
 msgid "Zoom In"
 msgstr "Tarkenna"
 
-#: ../src/maemo-mapper.c:6194
-#, fuzzy
+#: ../src/menu.c:1505
 msgid "Zoom Level"
-msgstr "Zoomaa tasolle"
+msgstr "Zoom taso"
 
-#: ../src/maemo-mapper.c:12121
+#: ../src/maps.c:2122
 msgid "Zoom Levels to Download: (0 = most detail)"
 msgstr "Ladattavat zoom tasot : (0 = tarkin)"
 
-#: ../src/maemo-mapper.c:6187 ../src/maemo-mapper.c:8050
+#: ../src/main.c:259 ../src/menu.c:1440
 msgid "Zoom Out"
 msgstr "Loitonna"
 
-#: ../src/maemo-mapper.c:8815 ../src/maemo-mapper.c:8928
-#: ../src/maemo-mapper.c:12356 ../src/maemo-mapper.c:12374
+#: ../src/input.c:103 ../src/input.c:290 ../src/menu.c:546 ../src/menu.c:564
 msgid "Zoom to Level"
 msgstr "Zoomaa tasolle"
 
-#: ../src/maemo-mapper.c:11890 ../src/maemo-mapper.c:11897
+#: ../src/maps.c:1880 ../src/maps.c:1887
 msgid "about"
 msgstr "noin"
 
-#: ../src/maemo-mapper.c:2708
+#: ../src/display.c:700
 msgid "in use"
 msgstr "käytössä"
 
-#: ../src/maemo-mapper.c:7999
+#: ../src/main.c:189
 msgid "km"
 msgstr "km"
 
-#: ../src/maemo-mapper.c:11810 ../src/maemo-mapper.c:11898
+#: ../src/maps.c:1791 ../src/maps.c:1888
 msgid "maps"
 msgstr "kartan palan lataus"
 
-#: ../src/maemo-mapper.c:11804 ../src/maemo-mapper.c:11891
+#: ../src/maps.c:1785 ../src/maps.c:1881
 msgid "maps "
 msgstr "kartan palan poisto"
 
-#: ../src/maemo-mapper.c:8000
+#: ../src/display.c:1466
+msgid "maps failed to download."
+msgstr ""
+
+#: ../src/main.c:190
 msgid "mi."
 msgstr "mi."
 
-#: ../src/maemo-mapper.c:8001
+#: ../src/main.c:191
 msgid "n.m."
 msgstr "n.m."
 
-#: ../src/maemo-mapper.c:2862
+#: ../src/display.c:854
 msgid "nofix"
 msgstr "nofix"
 
-#: ../src/maemo-mapper.c:2293 ../src/maemo-mapper.c:2871
+#: ../src/display.c:285 ../src/display.c:863
 msgid "none"
 msgstr "ei lainkaan"
 
-#: ../src/maemo-mapper.c:11810 ../src/maemo-mapper.c:11898
+#: ../src/maps.c:1791 ../src/maps.c:1888
 msgid "up to about"
 msgstr "noin"
 
+#~ msgid "Add"
+#~ msgstr "Lisää"
+
 #~ msgid ""
 #~ "Could not generate directions. Make sure your source and destination are "
 #~ "valid."
@@ -1376,14 +1642,53 @@ msgstr "noin"
 #~ msgid "Defaults"
 #~ msgstr "Oletukset"
 
+#~ msgid "Delete"
+#~ msgstr "Poista"
+
+#~ msgid "Dining"
+#~ msgstr "Ruokailu"
+
+#~ msgid "Downloading maps"
+#~ msgstr "Ladataan karttoja"
+
+#~ msgid "Edit"
+#~ msgstr "Muokkaa"
+
+#~ msgid ""
+#~ "Error in download.  Check internet connection and/or Map Repository URL "
+#~ "Format."
+#~ msgstr ""
+#~ "Virhe latauksessa. Tarkista Internet yhteys ja/tai karttavaraston URL:n "
+#~ "oikeellisuus."
+
 #~ msgid "Escape Key"
 #~ msgstr "Escape näppäin"
 
+#~ msgid "Fuel"
+#~ msgstr "Huoltoasemat"
+
 #~ msgid "GPS Mark"
 #~ msgstr "GPS merkki"
 
+#~ msgid "Keep Display On Only in Fullscreen Mode"
+#~ msgstr "Pidä näyttö päällä vain koko näytön ollessa käytössä"
+
 #~ msgid "No waypoints are visible."
 #~ msgstr "Kohdepisteitä ei ole näkyvissä."
 
 #~ msgid "No waypoints found."
 #~ msgstr "Kohdepisteitä ei löytynyt."
+
+#~ msgid ""
+#~ "Note: You can enter a device path\n"
+#~ "(e.g. \"/dev/rfcomm0\")."
+#~ msgstr ""
+#~ "Huom: Voit syöttää laitteen polun\n"
+#~ "(esim. \"/dev/rfcomm0\")."
+
+#  This word refers to Pitch as in of a person's voice.
+#~ msgid "Pitch"
+#~ msgstr "Korkeus"
+
+#~ msgid "Please specify a name for the POI."
+#~ msgstr "Määrittele POI pisteen nimi."
index d4e9e45831855363f99b00ab4e8630bddcfa288a..f63d66e64ca284ce417ee76b7a829f358a6e279b 100644 (file)
@@ -14,7 +14,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: it_IT\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-07-07 20:45-0400\n"
+"POT-Creation-Date: 2007-11-01 15:35-0400\n"
 "PO-Revision-Date: 2007-03-24 12:27GMT+1\n"
 "Last-Translator: alessandro pasotti <ale.pas@tiscalinet.it>\n"
 "Language-Team: italian <kde-i18n-it-admin@master.kde.org>\n"
@@ -24,73 +24,74 @@ msgstr ""
 "X-Generator: KBabel 1.11.2\n"
 "Plural-Forms:  nplurals=2; plural=(n != 1);\n"
 
-#: ../src/maemo-mapper.c:12960
+#: ../src/poi.c:922
 msgid "# POIs"
 msgstr "# POI"
 
-#: ../src/maemo-mapper.c:6293
+#: ../src/menu.c:1597
 msgid "About..."
 msgstr "Informazioni..."
 
-#: ../src/maemo-mapper.c:12916
-msgid "Add"
-msgstr "Aggiungi"
-
-#: ../src/maemo-mapper.c:12650
+#: ../src/poi.c:604
 msgid "Add Category"
 msgstr "Aggiungi categoria"
 
-#: ../src/maemo-mapper.c:13149
+#: ../src/poi.c:1123
 msgid "Add POI"
 msgstr "Aggiungi POI"
 
-#: ../src/maemo-mapper.c:6427 ../src/maemo-mapper.c:6456
+#: ../src/cmenu.c:610 ../src/cmenu.c:639
 msgid "Add POI..."
 msgstr "Aggiungi POI..."
 
-#: ../src/maemo-mapper.c:6423 ../src/maemo-mapper.c:6478
+#: ../src/cmenu.c:606 ../src/cmenu.c:661
 msgid "Add Route Point"
 msgstr "Aggiungi Punto Rotta"
 
-#: ../src/maemo-mapper.c:13601
+#: ../src/path.c:1334
 msgid "Add Waypoint"
 msgstr "Aggiungi Waypoint"
 
-#: ../src/maemo-mapper.c:6425 ../src/maemo-mapper.c:6480
+#: ../src/cmenu.c:608 ../src/cmenu.c:663
 msgid "Add Waypoint..."
 msgstr "Aggiungi Waypoint..."
 
-#: ../src/maemo-mapper.c:10910
+#: ../src/poi.c:878
+#, fuzzy
+msgid "Add..."
+msgstr "Aggiungi POI..."
+
+#: ../src/menu.c:837
 #, fuzzy
 msgid "Address"
 msgstr "Aggiungi"
 
-#: ../src/maemo-mapper.c:10987
+#: ../src/menu.c:862
 msgid "Address Located"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6256
+#: ../src/menu.c:1489
 #, fuzzy
 msgid "Address..."
 msgstr "Aggiungi POI..."
 
-#: ../src/maemo-mapper.c:5029
+#: ../src/settings.c:1126
 msgid "Advance Notice"
 msgstr "Anticipo avvisi"
 
-#: ../src/maemo-mapper.c:12100
+#: ../src/maps.c:2101
 msgid "Along Route - Radius (tiles):"
 msgstr "Lungo la rotta - raggio (riquadri):"
 
-#: ../src/maemo-mapper.c:2813
+#: ../src/display.c:805
 msgid "Altitude"
 msgstr "Altitudine"
 
-#: ../src/maemo-mapper.c:4501
+#: ../src/settings.c:548
 msgid "An error occurred while attempting to scan for bluetooth devices."
 msgstr "Si è verificato un errore cercando i dispositivi bluetooth."
 
-#: ../src/maemo-mapper.c:11489
+#: ../src/maps.c:1517
 msgid ""
 "An error occurred while retrieving the repositories.  The web service may be "
 "temporarily down."
@@ -98,7 +99,7 @@ msgstr ""
 "Si è verificato un errore cercando i depositi. Il web service potrebbe "
 "essere temporaneamente disattivato."
 
-#: ../src/maemo-mapper.c:8829
+#: ../src/gps.c:955
 msgid ""
 "An error occurred while trying to reset the bluetooth radio.\n"
 "\n"
@@ -110,145 +111,204 @@ msgstr ""
 "Sei sicuro di aver modificato il file\n"
 "/etc/sudoers?"
 
-#: ../src/maemo-mapper.c:5025
+#: ../src/settings.c:1122
 msgid "Announce"
 msgstr "Avviso"
 
-#: ../src/maemo-mapper.c:12137
+#: ../src/maps.c:2138
 msgid "Area"
 msgstr "Area"
 
-#: ../src/maemo-mapper.c:4994 ../src/maemo-mapper.c:6227
+#: ../src/menu.c:1540 ../src/settings.c:1061
 msgid "Auto-Center"
 msgstr "Centro automatico"
 
-#: ../src/maemo-mapper.c:10774
+#: ../src/menu.c:1114
 msgid "Auto-Center Mode: Lat/Lon"
 msgstr "Modalità centro automatico: Lat/Lon"
 
-#: ../src/maemo-mapper.c:10759
+#: ../src/menu.c:1097
 msgid "Auto-Center Mode: Lead"
 msgstr "Modalità centro automatico: vettore"
 
-#: ../src/maemo-mapper.c:10788
+#: ../src/menu.c:1130
 msgid "Auto-Center Off"
 msgstr "Disabilita centro automatico"
 
-#: ../src/maemo-mapper.c:6172
+#: ../src/menu.c:1419
 msgid "Auto-Download"
 msgstr "Scaricamento automatico"
 
-#: ../src/maemo-mapper.c:10064
+#: ../src/settings.c:1221
+#, fuzzy
+msgid "Auto-Download Pre-cache"
+msgstr "Scaricamento automatico"
+
+#: ../src/menu.c:1454
+#, fuzzy
+msgid "Auto-Rotate"
+msgstr "Aggiornamento automatico"
+
+#: ../src/menu.c:624
+msgid "Auto-Rotate Disabled"
+msgstr ""
+
+#: ../src/menu.c:619
+msgid "Auto-Rotate Enabled"
+msgstr ""
+
+#: ../src/path.c:1113
 msgid "Auto-Update"
 msgstr "Aggiornamento automatico"
 
-#: ../src/maemo-mapper.c:10076
+#: ../src/path.c:1119
 msgid "Avoid Highways"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8098
+#: ../src/poi.c:1749
+#, fuzzy
+msgid "Bear."
+msgstr "Cancella"
+
+#: ../src/main.c:310
+#, fuzzy
+msgid "Bluetooth"
+msgstr "Riavvia Bluetooth"
+
+#: ../src/main.c:307
 msgid "Bottom-Left"
 msgstr "Inferiore sinistro"
 
-#: ../src/maemo-mapper.c:8097 ../src/maemo-mapper.c:12208
+#: ../src/main.c:306 ../src/maps.c:2209
 msgid "Bottom-Right"
 msgstr "Inferiore destra"
 
-#: ../src/maemo-mapper.c:3767
+#: ../src/path.c:967
 msgid "Break already inserted."
 msgstr "Sosta già inserita."
 
-#: ../src/maemo-mapper.c:5191 ../src/maemo-mapper.c:11297
+#: ../src/poi.c:2509
+#, fuzzy
+msgid "Browse POIs"
+msgstr "Abilita POI"
+
+#: ../src/maps.c:1323 ../src/menu.c:1403 ../src/settings.c:1054
+#: ../src/settings.c:1278
 msgid "Browse..."
 msgstr "Scegli..."
 
-#: ../src/maemo-mapper.c:2996
+#: ../src/poi.c:153
 msgid "Bus stops, airports, train stations, etc."
 msgstr "Fermate bus, aereoporti, stazioni ecc."
 
-#: ../src/maemo-mapper.c:3001
+#: ../src/poi.c:158
 msgid "Business"
 msgstr "Affari"
 
-#: ../src/maemo-mapper.c:12091
+#: ../src/maps.c:2092
 msgid "By Area (see tab)"
 msgstr "Per area (vedi scheda)"
 
-#: ../src/maemo-mapper.c:11287
-msgid "Cache Dir."
+#: ../src/maps.c:1313
+#, fuzzy
+msgid "Cache DB"
 msgstr "Cartella cache"
 
-#: ../src/maemo-mapper.c:11227
+#: ../src/maps.c:1253
 msgid ""
 "Cannot delete the last repository - there must be at lease one repository."
 msgstr "Impossibile cancellare l'ultimo deposito - deve essercene almeno uno."
 
-#: ../src/maemo-mapper.c:12416
+#: ../src/menu.c:1177
+#, fuzzy
 msgid ""
-"Cannot enable GPS until a GPS Receiver MAC is set in the Settings dialog box."
+"Cannot enable GPS until a GPS receiver is set up in the Settings dialog box."
 msgstr ""
 "Impossibile abilitare il GPS finché non viene impostato un indirizzo MAC\n"
 "nella finestra Impostazioni."
 
-#: ../src/maemo-mapper.c:8597 ../src/maemo-mapper.c:13185
+#: ../src/menu.c:1405
+#, fuzzy
+msgid "Categories..."
+msgstr "Categorie POI..."
+
+#: ../src/poi.c:458 ../src/poi.c:1159 ../src/poi.c:1512 ../src/poi.c:1732
+#: ../src/poi.c:2089 ../src/poi.c:2243 ../src/poi.c:2540
 msgid "Category"
 msgstr "Categoria"
 
-#: ../src/maemo-mapper.c:6139 ../src/maemo-mapper.c:6159
-#: ../src/maemo-mapper.c:12044
+#: ../src/poi.c:1928 ../src/poi.c:2003
+msgid "Checked POI Actions..."
+msgstr ""
+
+#: ../src/maps.c:2045 ../src/menu.c:1371 ../src/menu.c:1391
 msgid "Clear"
 msgstr "Cancella"
 
-#: ../src/maemo-mapper.c:8060
+#: ../src/main.c:269
 #, fuzzy
 msgid "Clear Track"
 msgstr "Abilita tracce"
 
-#: ../src/maemo-mapper.c:6295
+#: ../src/menu.c:1448
+#, fuzzy
+msgid "Clockwise"
+msgstr "Chiudi"
+
+#: ../src/menu.c:1599
 msgid "Close"
 msgstr "Chiudi"
 
-#: ../src/maemo-mapper.c:4729
+#: ../src/settings.c:760
 msgid "Colors"
 msgstr "Colori"
 
-#: ../src/maemo-mapper.c:4953
+#: ../src/settings.c:993
 msgid "Colors..."
 msgstr "Colori..."
 
-#: ../src/maemo-mapper.c:11803 ../src/maemo-mapper.c:11890
+#: ../src/menu.c:1515
+msgid "Compass Rose"
+msgstr ""
+
+#: ../src/maps.c:1784 ../src/maps.c:1880
 msgid "Confirm DELETION of"
 msgstr "Conferma eliminazione di"
 
-#: ../src/maemo-mapper.c:11234
+#: ../src/maps.c:1260
 msgid "Confirm delete of repository"
 msgstr "Conferma l'eliminazione del deposito"
 
-#: ../src/maemo-mapper.c:13966
+#: ../src/cmenu.c:385
 msgid "Confirm delete of waypoint"
 msgstr "Conferma l'eliminazione del waypoint"
 
-#: ../src/maemo-mapper.c:11809 ../src/maemo-mapper.c:11896
+#: ../src/maps.c:1790 ../src/maps.c:1886
 msgid "Confirm download of"
 msgstr "Conferma il download di"
 
-#: ../src/maemo-mapper.c:4663
+#: ../src/settings.c:699
 msgid "Continue?"
 msgstr "Continuo?"
 
-#: ../src/maemo-mapper.c:13451
+#: ../src/display.c:2453
 msgid "Copy"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6446
+#: ../src/cmenu.c:629
 msgid "Copy Description"
 msgstr "Copia descrizione"
 
-#: ../src/maemo-mapper.c:6444
+#: ../src/cmenu.c:627
 msgid "Copy Lat/Lon"
 msgstr "Copia Lat/Lon"
 
-#: ../src/maemo-mapper.c:13684
+#: ../src/menu.c:1450
+#, fuzzy
+msgid "Counter"
+msgstr "Rotta"
+
+#: ../src/path.c:1417
 msgid ""
 "Creating a \"waypoint\" with no description actually adds a break point.  Is "
 "that what you want?"
@@ -256,336 +316,452 @@ msgstr ""
 "La creazione di un waypoint senza descrizione inserisce una sosta. È quello "
 "che intendi fare?"
 
-#: ../src/maemo-mapper.c:2286
+#: ../src/display.c:278
 msgid "DGPS"
 msgstr "DGPS"
 
-#: ../src/maemo-mapper.c:5129
+#: ../src/poi.c:2079
+#, fuzzy
+msgid "Default Category"
+msgstr "Elimina categoria?"
+
+#: ../src/settings.c:1208
 msgid "Degrees Format"
 msgstr "Formato gradi"
 
-#: ../src/maemo-mapper.c:12631 ../src/maemo-mapper.c:13124
-msgid "Delete"
-msgstr "Elimina"
-
-#: ../src/maemo-mapper.c:12081
+#: ../src/maps.c:2082
 msgid "Delete Maps"
 msgstr "Elimina mappe"
 
-#: ../src/maemo-mapper.c:13008
+#: ../src/poi.c:958
 msgid "Delete POI?"
 msgstr "Elimina POI?"
 
-#: ../src/maemo-mapper.c:12552
+#: ../src/poi.c:506
 msgid "Delete category?"
 msgstr "Elimina categoria?"
 
-#: ../src/maemo-mapper.c:6453 ../src/maemo-mapper.c:11586
+#: ../src/poi.c:1843
+#, fuzzy
+msgid "Delete selected POI?"
+msgstr "Elimina POI?"
+
+#: ../src/cmenu.c:636 ../src/maps.c:1614 ../src/poi.c:585 ../src/poi.c:1096
+#: ../src/poi.c:1943
 msgid "Delete..."
 msgstr "Elimina..."
 
-#: ../src/maemo-mapper.c:4489 ../src/maemo-mapper.c:10513
-#: ../src/maemo-mapper.c:12669 ../src/maemo-mapper.c:12955
-#: ../src/maemo-mapper.c:13212 ../src/maemo-mapper.c:13626
+#: ../src/menu.c:310 ../src/path.c:1359 ../src/poi.c:623 ../src/poi.c:917
+#: ../src/poi.c:1174 ../src/settings.c:536
 msgid "Description"
 msgstr "Descrizione"
 
-#: ../src/maemo-mapper.c:10093
+#: ../src/path.c:1136
 msgid "Destination"
 msgstr "Destinazione"
 
-#: ../src/maemo-mapper.c:6278
+#: ../src/menu.c:1582
 msgid "Details..."
 msgstr "Dettagli..."
 
-#: ../src/maemo-mapper.c:2989
-msgid "Dining"
-msgstr "Ristorazione"
+#: ../src/gps.c:779
+#, fuzzy
+msgid "Disconnecting from GPS receiver"
+msgstr "Sto cercando un ricevitore GPS"
 
-#: ../src/maemo-mapper.c:3365 ../src/maemo-mapper.c:3425
-#: ../src/maemo-mapper.c:13566
+#: ../src/poi.c:1740
+#, fuzzy
+msgid "Dist."
+msgstr "Distanza"
+
+#: ../src/cmenu.c:136 ../src/path.c:517 ../src/path.c:577
 msgid "Distance"
 msgstr "Distanza"
 
-#: ../src/maemo-mapper.c:11354
+#: ../src/maps.c:1382
 msgid "Double Pixels"
 msgstr "Pixel doppi"
 
-#: ../src/maemo-mapper.c:12068
+#: ../src/main.c:195 ../src/menu.c:1466
+msgid "Down"
+msgstr ""
+
+#: ../src/maps.c:2069
 msgid "Download Maps"
 msgstr "Scaricamento mappe"
 
-#: ../src/maemo-mapper.c:10034
+#: ../src/poi.c:2202
+#, fuzzy
+msgid "Download POIs"
+msgstr "Scaricamento mappe"
+
+#: ../src/path.c:1071
 msgid "Download Route"
 msgstr "Scarica rotta"
 
-#: ../src/maemo-mapper.c:6420 ../src/maemo-mapper.c:6451
-#: ../src/maemo-mapper.c:6475
+#: ../src/cmenu.c:603 ../src/cmenu.c:634 ../src/cmenu.c:658
 msgid "Download Route to..."
 msgstr "Scarica la rotta per..."
 
-#: ../src/maemo-mapper.c:11317
+#: ../src/maps.c:1345
 msgid "Download Zoom Steps"
 msgstr "Passi di zoom per lo scaricamento"
 
-#: ../src/maemo-mapper.c:6129 ../src/maemo-mapper.c:11567
+#: ../src/maps.c:1595 ../src/menu.c:1361 ../src/menu.c:1401
 msgid "Download..."
 msgstr "Scarica..."
 
-#: ../src/maemo-mapper.c:6937
-msgid "Downloading maps"
-msgstr "Scaricamento mappe in corso"
+#: ../src/maps.c:654 ../src/maps.c:667
+msgid "Downloaded maps will not be cached."
+msgstr ""
 
-#: ../src/maemo-mapper.c:12913
-msgid "Edit"
-msgstr "Modifica"
+#: ../src/menu.c:1479
+#, fuzzy
+msgid "East"
+msgstr "Scorri verso est"
 
-#: ../src/maemo-mapper.c:13208
+#: ../src/poi.c:1170
 msgid "Edit Categories..."
 msgstr "Modifica categorie"
 
-#: ../src/maemo-mapper.c:12625
+#: ../src/poi.c:579
 msgid "Edit Category"
 msgstr "Modifica categoria"
 
-#: ../src/maemo-mapper.c:13118
+#: ../src/poi.c:1090
 msgid "Edit POI"
 msgstr "Modifica POI"
 
-#: ../src/maemo-mapper.c:3000
+#: ../src/poi.c:875 ../src/poi.c:1999
+#, fuzzy
+msgid "Edit..."
+msgstr "Mostra/Modifica..."
+
+#: ../src/poi.c:157
 msgid "Elementary schools, college campuses, etc."
 msgstr "Scuole primarie, college ecc."
 
-#: ../src/maemo-mapper.c:6270
+#: ../src/menu.c:1574
 msgid "Enable GPS"
 msgstr "Abilita GPS"
 
-#: ../src/maemo-mapper.c:5042
+#: ../src/settings.c:1139
 msgid "Enable Voice Synthesis (requires flite)"
 msgstr "Abilita sintesi vocale (necessita di flite)"
 
-#: ../src/maemo-mapper.c:12693 ../src/maemo-mapper.c:12945
+#: ../src/poi.c:647 ../src/poi.c:907
 msgid "Enabled"
 msgstr "Abilitato"
 
-#: ../src/maemo-mapper.c:7185
-msgid ""
-"Error in download.  Check internet connection and/or Map Repository URL "
-"Format."
+#: ../src/poi.c:1305
+#, fuzzy
+msgid "Error adding POI"
+msgstr "Problema aggiungendo il POI"
+
+#: ../src/poi.c:710
+#, fuzzy
+msgid "Error adding category"
+msgstr "Problema aggiungendo la categoria"
+
+#: ../src/gps.c:631
+#, fuzzy
+msgid "Error connecting to GPS receiver."
+msgstr "Impossibile connettersi al ricevitore GPS. Riprovo?"
+
+#: ../src/gps.c:617
+msgid "Error connecting to GPSD."
 msgstr ""
-"Errore nello scaricamento. Controlla la connessione a internet e/o  l'URL "
-"del deposito."
 
-#: ../src/maemo-mapper.c:8371 ../src/maemo-mapper.c:10319
-#: ../src/maemo-mapper.c:10363 ../src/maemo-mapper.c:10437
+#: ../src/poi.c:521 ../src/poi.c:969 ../src/poi.c:1871
+#, fuzzy
+msgid "Error deleting POI"
+msgstr "Problema rimuovendo il POI"
+
+#: ../src/poi.c:530
+#, fuzzy
+msgid "Error deleting category"
+msgstr "Problema rimuovendo la categoria"
+
+#: ../src/main.c:488 ../src/menu.c:122 ../src/menu.c:234 ../src/path.c:678
+#: ../src/poi.c:2130 ../src/poi.c:2481
 msgid "Error parsing GPX file."
 msgstr "Errore analizzando il file GPX."
 
-#: ../src/maemo-mapper.c:1501
+#: ../src/gps.c:667
+#, fuzzy
+msgid "Error reading GPS data."
+msgstr "Errore analizzando il file GPX."
+
+#: ../src/poi.c:754
+#, fuzzy
+msgid "Error updating Category"
+msgstr "Problema aggiornando la categoria"
+
+#: ../src/poi.c:1285 ../src/poi.c:1583
+#, fuzzy
+msgid "Error updating POI"
+msgstr "Problema aggiornando il POI"
+
+#: ../src/poi.c:695
+#, fuzzy
+msgid "Error updating category"
+msgstr "Problema aggiornando la categoria"
+
+#: ../src/gpx.c:478 ../src/gpx.c:805
 msgid "Error while writing to file"
 msgstr "Errore scrivendo sul file"
 
-#: ../src/maemo-mapper.c:10459 ../src/maemo-mapper.c:10618
+#: ../src/poi.c:103
+#, fuzzy
+msgid "Error with POI database"
+msgstr "Problema coni il database dei POI"
+
+#: ../src/menu.c:153 ../src/menu.c:256 ../src/poi.c:1911
 msgid "Error writing GPX file."
 msgstr "Errore scrivendo il file GPX."
 
-#: ../src/maemo-mapper.c:3148
+#: ../src/gps.c:801
 msgid "Establishing GPS fix"
 msgstr "Connessione con il GPS in corso"
 
-#: ../src/maemo-mapper.c:2290
+#: ../src/display.c:282
 msgid "Estimated"
 msgstr "Stimato"
 
-#: ../src/maemo-mapper.c:3903
-msgid "Failed to connect to GPS receiver.  Retry?"
+#: ../src/poi.c:1948
+msgid "Export to GPX..."
+msgstr ""
+
+#: ../src/gps.c:923
+#, fuzzy
+msgid "Failed to connect to Bluetooth GPS receiver."
 msgstr "Impossibile connettersi al ricevitore GPS. Riprovo?"
 
-#: ../src/maemo-mapper.c:10251 ../src/maemo-mapper.c:10957
+#: ../src/util.c:139
 msgid "Failed to connect to GPX Directions server"
 msgstr "Impossibile connettersi al server delle indicazioni GPX"
 
-#: ../src/maemo-mapper.c:5577
+#: ../src/settings.c:1646
 msgid "Failed to initialize GConf.  Quitting."
 msgstr "Impossibile inizializzare GConf.  Esco."
 
-#: ../src/maemo-mapper.c:4047
+#: ../src/settings.c:72
 msgid "Failed to initialize GConf.  Settings were not saved."
 msgstr ""
 "Impossibile inizializzare GConf.  Le impostazioni non sono state salvate."
 
-#: ../src/maemo-mapper.c:7750 ../src/maemo-mapper.c:8360
+#: ../src/display.c:2561 ../src/main.c:476
 msgid "Failed to open file for reading"
 msgstr "Impossibile aprire il file per lettura"
 
-#: ../src/maemo-mapper.c:7403 ../src/maemo-mapper.c:7751
+#: ../src/display.c:2562
 msgid "Failed to open file for writing"
 msgstr "Impossibile aprire il file in scrittura"
 
-#: ../src/maemo-mapper.c:3014
+#: ../src/maps.c:652 ../src/maps.c:666
+#, fuzzy
+msgid "Failed to open map database for repository"
+msgstr "Impossibile aprire o creare il database"
+
+#: ../src/poi.c:171
 msgid "Failed to open or create database"
 msgstr "Impossibile aprire o creare il database"
 
-#: ../src/maemo-mapper.c:1502
+#: ../src/path.c:1553
+msgid "Failed to open path database. Tracks and routes will not be saved."
+msgstr ""
+
+#: ../src/path.c:195 ../src/path.c:221 ../src/path.c:240
+msgid "Failed to write to path database. Tracks and routes may not be saved."
+msgstr ""
+
+#: ../src/main.c:312
+msgid "File"
+msgstr ""
+
+#: ../src/settings.c:1044
+msgid "File Path"
+msgstr ""
+
+#: ../src/gpx.c:479 ../src/gpx.c:806
 msgid "File is incomplete."
 msgstr "Il file è incompleto."
 
-#: ../src/maemo-mapper.c:2858
+#: ../src/display.c:850
 msgid "Fix"
 msgstr "Fix"
 
-#: ../src/maemo-mapper.c:2867
+#: ../src/display.c:859
 msgid "Fix Quality"
 msgstr "Qualità Fix"
 
-#: ../src/maemo-mapper.c:2289
+#: ../src/settings.c:1093
+#, fuzzy
+msgid "Fixed"
+msgstr "Fix"
+
+#: ../src/display.c:281
 msgid "Float RTK"
 msgstr "Float RTK"
 
-#: ../src/maemo-mapper.c:13442
+#: ../src/display.c:2444
 #, fuzzy
 msgid "Format"
 msgstr "Formato URL"
 
-#: ../src/maemo-mapper.c:2985
-msgid "Fuel"
-msgstr "Carburante"
-
-#: ../src/maemo-mapper.c:6189
+#: ../src/menu.c:1564
 msgid "Full Screen"
 msgstr "Schermo intero"
 
-#: ../src/maemo-mapper.c:4747 ../src/maemo-mapper.c:4964
-#: ../src/maemo-mapper.c:6266
+#: ../src/menu.c:1570 ../src/settings.c:778 ../src/settings.c:1004
 msgid "GPS"
 msgstr "GPS"
 
-#: ../src/maemo-mapper.c:2761
+#: ../src/display.c:753
 msgid "GPS Details"
 msgstr "Dettagli GPS"
 
-#: ../src/maemo-mapper.c:2774
+#: ../src/display.c:766
 msgid "GPS Information"
 msgstr "Informazioni GPS"
 
-#: ../src/maemo-mapper.c:6258 ../src/maemo-mapper.c:12151
+#: ../src/maps.c:2152 ../src/menu.c:1491
 msgid "GPS Location"
 msgstr "Località GPS"
 
-#: ../src/maemo-mapper.c:3004
+#: ../src/main.c:311
+#, fuzzy
+msgid "GPSD"
+msgstr "GPS"
+
+#: ../src/settings.c:1025
+msgid "GPSD Host"
+msgstr ""
+
+#: ../src/poi.c:161
 msgid "General landmarks."
 msgstr "Generale - territorio."
 
-#: ../src/maemo-mapper.c:3002
+#: ../src/poi.c:159
 msgid "General places of business."
 msgstr "Generale - affari."
 
-#: ../src/maemo-mapper.c:6250
+#: ../src/menu.c:1483 ../src/poi.c:1996
 msgid "Go to"
 msgstr "Vai a"
 
-#: ../src/maemo-mapper.c:10900
+#: ../src/menu.c:827
 msgid "Go to Address"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10806
+#: ../src/menu.c:731
 msgid "Go to Lat/Lon"
 msgstr "Vai a Lat/Lon"
 
-#: ../src/maemo-mapper.c:6483
+#: ../src/cmenu.c:666
 msgid "Go to Nearest"
 msgstr "Vai al più vicino"
 
-#: ../src/maemo-mapper.c:6460
+#: ../src/cmenu.c:643
 msgid "Go to Next"
 msgstr "Vai al prossimo"
 
-#: ../src/maemo-mapper.c:4608
+#: ../src/settings.c:644
 msgid "Hardware Keys"
 msgstr "Tasti hardware"
 
-#: ../src/maemo-mapper.c:4950
+#: ../src/settings.c:990
 msgid "Hardware Keys..."
 msgstr "Tasti hardware..."
 
-#: ../src/maemo-mapper.c:2822
+#: ../src/display.c:814
 msgid "Heading"
 msgstr "Direzione"
 
-#: ../src/maemo-mapper.c:6291
+#: ../src/menu.c:1595
 msgid "Help..."
 msgstr "Aiuto..."
 
-#: ../src/maemo-mapper.c:2988
+#: ../src/poi.c:145
 msgid "Houses, apartments, or other residences of import."
 msgstr "Case appartamenti o altre residenze."
 
-#: ../src/maemo-mapper.c:12937
+#: ../src/poi.c:899
 msgid "ID"
 msgstr "ID"
 
-#: ../src/maemo-mapper.c:2994
+#: ../src/menu.c:1399
+msgid "Import..."
+msgstr ""
+
+#: ../src/poi.c:151
 msgid "Indoor or Outdoor places to have fun."
 msgstr "Luoghi di divertimento."
 
-#: ../src/maemo-mapper.c:5102
-msgid "Information Font Size"
+#: ../src/settings.c:1174
+#, fuzzy
+msgid "Info Font Size"
 msgstr "Dimensione catattere Informazioni"
 
-#: ../src/maemo-mapper.c:6151
+#: ../src/menu.c:1383
 msgid "Insert Break"
 msgstr "Inserisci sosta"
 
-#: ../src/maemo-mapper.c:10493
+#: ../src/menu.c:290
 msgid "Insert Mark"
 msgstr "Inserisci segnale"
 
-#: ../src/maemo-mapper.c:6153
+#: ../src/menu.c:1385
 msgid "Insert Mark..."
 msgstr "Inserisci segnale..."
 
-#: ../src/maemo-mapper.c:8059
+#: ../src/main.c:268
 msgid "Insert Track Break"
 msgstr "Inserisci sosta"
 
-#: ../src/maemo-mapper.c:12324
+#: ../src/maps.c:2342
 msgid "Invalid Bottom-Right Latitude"
 msgstr "Latitudine inferiore destra errata"
 
-#: ../src/maemo-mapper.c:12331
+#: ../src/maps.c:2349
 msgid "Invalid Bottom-Right Longitude"
 msgstr "Longitudine inferiore destra errata"
 
-#: ../src/maemo-mapper.c:10865 ../src/maemo-mapper.c:13267
+#: ../src/menu.c:792 ../src/poi.c:1224
 msgid "Invalid Latitude"
 msgstr "Latitudine errata"
 
-#: ../src/maemo-mapper.c:10872 ../src/maemo-mapper.c:13274
+#: ../src/menu.c:799 ../src/poi.c:1231
 msgid "Invalid Longitude"
 msgstr "Longitudine errata"
 
-#: ../src/maemo-mapper.c:9534 ../src/maemo-mapper.c:9545
+#: ../src/gps.c:66 ../src/gps.c:77
 msgid "Invalid NMEA input from receiver!"
 msgstr "Dati NMEA dal ricevitore errati!"
 
-#: ../src/maemo-mapper.c:12310
+#: ../src/maps.c:2328
 msgid "Invalid Top-Left Latitude"
 msgstr "Latitudine superiore sinistra errata"
 
-#: ../src/maemo-mapper.c:12317
+#: ../src/maps.c:2335
 msgid "Invalid Top-Left Longitude"
 msgstr "Longitudine superiore sinistra errata"
 
-#: ../src/maemo-mapper.c:10971
+#: ../src/util.c:150
 #, fuzzy
 msgid "Invalid address."
 msgstr "Latitudine superiore sinistra errata"
 
-#: ../src/maemo-mapper.c:10264
+#: ../src/poi.c:2460
+#, fuzzy
+msgid "Invalid origin or query."
+msgstr "Longitudine errata"
+
+#: ../src/path.c:657
 msgid "Invalid source or destination."
 msgstr ""
 
-#: ../src/maemo-mapper.c:6562
+#: ../src/display.c:1077
 msgid ""
 "It looks like this is your first time running Maemo Mapper.  Press OK to "
 "view the the help pages. Otherwise, press Cancel to continue."
@@ -593,79 +769,82 @@ msgstr ""
 "Sembra che sia la prima volta che avvii Maemo Mapper. Premi Ok per "
 "visualizzare il manuale. Oppure premi Annulla per continuare."
 
-#: ../src/maemo-mapper.c:5094
-msgid "Keep Display On Only in Fullscreen Mode"
-msgstr "Mantieni lo schermo sempre acceso solo quando full-screen"
-
-#: ../src/maemo-mapper.c:8592 ../src/maemo-mapper.c:12661
-#: ../src/maemo-mapper.c:12950 ../src/maemo-mapper.c:13177
+#: ../src/poi.c:453 ../src/poi.c:615 ../src/poi.c:912 ../src/poi.c:1151
+#: ../src/poi.c:1757
 msgid "Label"
 msgstr "Etichetta"
 
-#: ../src/maemo-mapper.c:3003
+#: ../src/poi.c:160
 msgid "Landmark"
 msgstr "Punto di riferimento sul territorio"
 
-#: ../src/maemo-mapper.c:13161 ../src/maemo-mapper.c:13424
+#: ../src/display.c:2426 ../src/poi.c:1135
 msgid "Lat"
 msgstr "Lat, Lon"
 
-#: ../src/maemo-mapper.c:10503 ../src/maemo-mapper.c:13611
+#: ../src/menu.c:300 ../src/path.c:1344
 msgid "Lat, Lon:"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6231
+#: ../src/menu.c:1544
 msgid "Lat/Lon"
 msgstr "Lat/Lon"
 
-#: ../src/maemo-mapper.c:6254
+#: ../src/menu.c:1487
 msgid "Lat/Lon..."
 msgstr "Lat/Lon..."
 
-#: ../src/maemo-mapper.c:2786 ../src/maemo-mapper.c:10816
-#: ../src/maemo-mapper.c:12141 ../src/maemo-mapper.c:13512
+#: ../src/cmenu.c:82 ../src/display.c:778 ../src/maps.c:2142 ../src/menu.c:741
 msgid "Latitude"
 msgstr "Latitudine"
 
-#: ../src/maemo-mapper.c:6237
+#: ../src/menu.c:1550
 msgid "Lead"
 msgstr "Anticipo"
 
-#: ../src/maemo-mapper.c:5011
+#: ../src/settings.c:1078
 msgid "Lead Amount"
 msgstr "Lunghezza anticipo"
 
-#: ../src/maemo-mapper.c:5082
+#: ../src/main.c:196 ../src/menu.c:1468
+#, fuzzy
+msgid "Left"
+msgstr "Superiore sinistra"
+
+#: ../src/settings.c:1151
 msgid "Line Width"
 msgstr "Spessore linea"
 
-#: ../src/maemo-mapper.c:2831
+#: ../src/display.c:823
 msgid "Local time"
 msgstr "Ora locale"
 
-#: ../src/maemo-mapper.c:5162 ../src/maemo-mapper.c:6409
-#: ../src/maemo-mapper.c:8587
+#: ../src/cmenu.c:592 ../src/poi.c:448 ../src/settings.c:1249
 msgid "Location"
 msgstr "Località"
 
-#: ../src/maemo-mapper.c:2997
+#: ../src/poi.c:154
 msgid "Lodging"
 msgstr "Lodging"
 
-#: ../src/maemo-mapper.c:13169 ../src/maemo-mapper.c:13433
+#: ../src/display.c:2435 ../src/poi.c:1143
 msgid "Lon"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2795 ../src/maemo-mapper.c:10829
-#: ../src/maemo-mapper.c:12145 ../src/maemo-mapper.c:13513
+#: ../src/cmenu.c:83 ../src/display.c:787 ../src/maps.c:2146 ../src/menu.c:755
 msgid "Longitude"
 msgstr "Longitudine"
 
-#: ../src/maemo-mapper.c:4484 ../src/maemo-mapper.c:4968
+#: ../src/settings.c:531
 msgid "MAC"
 msgstr "MAC"
 
-#: ../src/maemo-mapper.c:11470
+#: ../src/settings.c:1009
+#, fuzzy
+msgid "MAC Address"
+msgstr "Aggiungi"
+
+#: ../src/maps.c:1498
 msgid ""
 "Maemo Mapper will now download and add a list of possibly-duplicate "
 "repositories from the internet.  Continue?"
@@ -673,47 +852,47 @@ msgstr ""
 "Maemo Mapper sta per scaricare e aggiungere una lista di depositi (forse "
 "duplicati) da internet. Continuo?"
 
-#: ../src/maemo-mapper.c:12033
+#: ../src/maps.c:2034
 msgid "Manage Maps"
 msgstr "Gestisci mappe"
 
-#: ../src/maemo-mapper.c:6168
+#: ../src/menu.c:1415
 msgid "Manage Maps..."
 msgstr "Gestisci mappe..."
 
-#: ../src/maemo-mapper.c:11550
+#: ../src/maps.c:1578
 msgid "Manage Repositories"
 msgstr "Gestisci depositi"
 
-#: ../src/maemo-mapper.c:6170
+#: ../src/menu.c:1417
 msgid "Manage Repositories..."
 msgstr "Gestisci depositi..."
 
-#: ../src/maemo-mapper.c:2291
+#: ../src/display.c:283
 msgid "Manual"
 msgstr "Manuale"
 
-#: ../src/maemo-mapper.c:6163
+#: ../src/menu.c:1410
 msgid "Maps"
 msgstr "Mappe"
 
-#: ../src/maemo-mapper.c:2876
+#: ../src/display.c:868
 msgid "Max speed"
 msgstr "Velocità massima"
 
-#: ../src/maemo-mapper.c:5078
+#: ../src/settings.c:1147
 msgid "Misc."
 msgstr "Varie"
 
-#: ../src/maemo-mapper.c:5114
+#: ../src/settings.c:1204
 msgid "Misc. 2"
 msgstr "Varie 2"
 
-#: ../src/maemo-mapper.c:3006
+#: ../src/poi.c:163
 msgid "Miscellaneous category for everything else."
 msgstr "Categorie miste"
 
-#: ../src/maemo-mapper.c:12285 ../src/maemo-mapper.c:12449
+#: ../src/maps.c:2294 ../src/menu.c:520
 msgid ""
 "NOTE: You must set a Map URI in the current repository in order to download "
 "maps."
@@ -721,63 +900,66 @@ msgstr ""
 "NOTA: Devi impostare un URI per le mappe nel gestore dei depositi prima di "
 "poter scaricare delle mappe."
 
-#: ../src/maemo-mapper.c:11171 ../src/maemo-mapper.c:11409
+#: ../src/maps.c:1197 ../src/maps.c:1437
 msgid "Name"
 msgstr "Nome"
 
-#: ../src/maemo-mapper.c:6262
+#: ../src/menu.c:1495
 msgid "Nearest POI"
 msgstr "POI più vicino"
 
-#: ../src/maemo-mapper.c:11161
+#: ../src/maps.c:1187
 msgid "New Name"
 msgstr "Nuovo nome"
 
-#: ../src/maemo-mapper.c:11399
+#: ../src/maps.c:1427
 msgid "New Repository"
 msgstr "Nuovo deposito"
 
-#: ../src/maemo-mapper.c:11589
+#: ../src/maps.c:1617
 msgid "New..."
 msgstr "Nuovo..."
 
-#: ../src/maemo-mapper.c:6260
+#: ../src/menu.c:1493
 msgid "Next Waypoint"
 msgstr "Prossimo waypoint"
 
-#: ../src/maemo-mapper.c:11362
+#: ../src/maps.c:1390
 msgid "Next-able"
 msgstr "Prossimo"
 
-#: ../src/maemo-mapper.c:5283
+#: ../src/settings.c:1472
+#, fuzzy
 msgid ""
-"No GPS Receiver MAC provided.\n"
+"No GPS Receiver provided.\n"
 "GPS will be disabled."
 msgstr ""
 "Nessun indirizzo MAC impostato per il ricevitore GPS.\n"
 "GPS disabilitato."
 
-#: ../src/maemo-mapper.c:8530 ../src/maemo-mapper.c:11082
+#: ../src/menu.c:950 ../src/poi.c:391 ../src/poi.c:2772
 msgid "No POIs found."
 msgstr "Nessun POI trovato."
 
-#: ../src/maemo-mapper.c:6243
+#: ../src/poi.c:1401
+#, fuzzy
+msgid "No POIs were found."
+msgstr "Nessun POI trovato."
+
+#: ../src/main.c:309 ../src/menu.c:1556
 msgid "None"
 msgstr "Nessuno"
 
-#: ../src/maemo-mapper.c:4984
-msgid ""
-"Note: You can enter a device path\n"
-"(e.g. \"/dev/rfcomm0\")."
-msgstr ""
-"Nota: puoi inserire un percorso al dispositivo\n"
-"(es.   \"/dev/rfcomm0\")."
+#: ../src/menu.c:1473
+#, fuzzy
+msgid "North"
+msgstr "Scorri verso nord"
 
-#: ../src/maemo-mapper.c:6127 ../src/maemo-mapper.c:6147
+#: ../src/menu.c:1359 ../src/menu.c:1379
 msgid "Open..."
 msgstr "Apri..."
 
-#: ../src/maemo-mapper.c:6572
+#: ../src/display.c:1087
 msgid ""
 "OpenStreetMap.org provides public, free-to-use maps.  You can also download "
 "a sample set of repositories from  the internet by using the \"Download...\" "
@@ -786,511 +968,600 @@ msgstr ""
 "OpenStreetMap.org fornisce mappe pubbliche e libere. Puoi anche scaricare un "
 "set di depositi di esempio da internet usando il pulsante \"Scarica...\" "
 
-#: ../src/maemo-mapper.c:10083
+#: ../src/path.c:1126 ../src/poi.c:2268 ../src/poi.c:2565
 msgid "Origin"
 msgstr "Partenza"
 
-#: ../src/maemo-mapper.c:3005
+#: ../src/poi.c:162
 msgid "Other"
 msgstr "Altro"
 
-#: ../src/maemo-mapper.c:12075
+#: ../src/maps.c:2076
 msgid "Overwrite"
 msgstr "Sovrascrivi"
 
-#: ../src/maemo-mapper.c:4792 ../src/maemo-mapper.c:5177
-#: ../src/maemo-mapper.c:6464
+#: ../src/cmenu.c:647 ../src/menu.c:1395 ../src/menu.c:1534
+#: ../src/settings.c:823 ../src/settings.c:1264
 msgid "POI"
 msgstr "POI"
 
-#: ../src/maemo-mapper.c:12903
+#: ../src/poi.c:865
 msgid "POI Categories"
 msgstr "Categorie POI"
 
-#: ../src/maemo-mapper.c:6222
-msgid "POI Categories..."
-msgstr "Categorie POI..."
+#: ../src/poi.c:1987
+#, fuzzy
+msgid "POI List"
+msgstr "POI"
 
-#: ../src/maemo-mapper.c:5181
+#: ../src/settings.c:1268
 msgid "POI database"
 msgstr "Database POI"
 
-#: ../src/maemo-mapper.c:6218
-msgid "POIs"
-msgstr "POI"
+#: ../src/poi.c:1907
+msgid "POIs Exported"
+msgstr ""
+
+#: ../src/poi.c:1395
+msgid ""
+"POIs were added to the POI database.  The following screen will allow you to "
+"modify or delete any of the new POIs."
+msgstr ""
 
-#: ../src/maemo-mapper.c:2287
+#: ../src/display.c:279
 msgid "PPS"
 msgstr "PPS"
 
-#: ../src/maemo-mapper.c:8044
+#: ../src/poi.c:2252
+msgid "Page"
+msgstr ""
+
+#: ../src/menu.c:1460
+msgid "Pan"
+msgstr ""
+
+#: ../src/main.c:245
 msgid "Pan East"
 msgstr "Scorri verso est"
 
-#: ../src/maemo-mapper.c:8041
+#: ../src/main.c:242
 msgid "Pan North"
 msgstr "Scorri verso nord"
 
-#: ../src/maemo-mapper.c:8043
+#: ../src/settings.c:1065
+#, fuzzy
+msgid "Pan Sensitivity"
+msgstr "Sensibilità"
+
+#: ../src/main.c:244
 msgid "Pan South"
 msgstr "Scorri verso sud"
 
-#: ../src/maemo-mapper.c:8042
+#: ../src/main.c:243
 msgid "Pan West"
 msgstr "Scorri verso ovest"
 
-#  This word refers to Pitch as in of a person's voice.
-#: ../src/maemo-mapper.c:5067
-msgid "Pitch"
-msgstr "Intonazione"
-
-#: ../src/maemo-mapper.c:2990
+#: ../src/poi.c:147
 msgid "Places to eat or drink."
 msgstr "Luoghi dove bere o mangiare."
 
-#: ../src/maemo-mapper.c:2992
+#: ../src/poi.c:149
 msgid "Places to shop or acquire services."
 msgstr "Luoghi dove acquistare beni o servizi."
 
-#: ../src/maemo-mapper.c:2998
+#: ../src/poi.c:155
 msgid "Places to stay temporarily or for the night."
 msgstr "Luoghi dove pernottare."
 
-#: ../src/maemo-mapper.c:10567
+#: ../src/menu.c:364
 msgid "Please provide a description for the mark."
 msgstr "Specifica una descrizione per il POI."
 
-#: ../src/maemo-mapper.c:4519
+#: ../src/settings.c:566
 msgid "Please select a bluetooth device from the list."
 msgstr "Scegli dalla lista un dispositivo bluetooth."
 
-#: ../src/maemo-mapper.c:13289
-msgid "Please specify a category for the POI."
+#: ../src/poi.c:1250 ../src/poi.c:1532
+#, fuzzy
+msgid "Please specify a category."
 msgstr "Specifica una categoria per il POI."
 
-#: ../src/maemo-mapper.c:13282
-msgid "Please specify a name for the POI."
-msgstr "Specifica un nome per il POI."
+#: ../src/poi.c:2104 ../src/poi.c:2425
+#, fuzzy
+msgid "Please specify a default category."
+msgstr "Specifica un nome per la categoria."
 
-#: ../src/maemo-mapper.c:12719
+#: ../src/poi.c:673
 msgid "Please specify a name for the category."
 msgstr "Specifica un nome per la categoria."
 
-#: ../src/maemo-mapper.c:10173
+#: ../src/poi.c:1243
+#, fuzzy
+msgid "Please specify a name."
+msgstr "Specifica un URL."
+
+#: ../src/poi.c:2432
+#, fuzzy
+msgid "Please specify a query."
+msgstr "Specifica un URL."
+
+#: ../src/path.c:1214 ../src/poi.c:2368
 msgid "Please specify a source URL."
 msgstr "Specifica un URL."
 
-#: ../src/maemo-mapper.c:10217
+#: ../src/path.c:1256
 msgid "Please specify a start location."
 msgstr "Indica una località di partenza."
 
-#: ../src/maemo-mapper.c:10941
-#, fuzzy
-msgid "Please specify an address."
-msgstr "Specifica un URL."
-
-#: ../src/maemo-mapper.c:10224
+#: ../src/path.c:1263
 msgid "Please specify an end location."
 msgstr "Indica una località di arrivo."
 
-#: ../src/maemo-mapper.c:13340
-msgid "Problem adding POI"
-msgstr "Problema aggiungendo il POI"
-
-#: ../src/maemo-mapper.c:12756
-msgid "Problem adding category"
-msgstr "Problema aggiungendo la categoria"
-
-#: ../src/maemo-mapper.c:12567 ../src/maemo-mapper.c:13019
-msgid "Problem deleting POI"
-msgstr "Problema rimuovendo il POI"
-
-#: ../src/maemo-mapper.c:12576
-msgid "Problem deleting category"
-msgstr "Problema rimuovendo la categoria"
+#: ../src/poi.c:2419 ../src/poi.c:2696
+#, fuzzy
+msgid "Please specify an origin."
+msgstr "Indica una località di arrivo."
 
-#: ../src/maemo-mapper.c:12795
-msgid "Problem updating Category"
-msgstr "Problema aggiornando la categoria"
+#: ../src/settings.c:1110
+msgid "Points"
+msgstr ""
 
-#: ../src/maemo-mapper.c:13318
-msgid "Problem updating POI"
-msgstr "Problema aggiornando il POI"
+#: ../src/settings.c:1035
+#, fuzzy
+msgid "Port"
+msgstr "Scorri verso nord"
 
-#: ../src/maemo-mapper.c:12741
-msgid "Problem updating category"
-msgstr "Problema aggiornando la categoria"
+#: ../src/maps.c:850
+msgid "Processing Maps"
+msgstr ""
 
-#: ../src/maemo-mapper.c:2946
-msgid "Problem with POI database"
-msgstr "Problema coni il database dei POI"
+#: ../src/poi.c:2278 ../src/poi.c:2575
+msgid "Query"
+msgstr ""
 
-#: ../src/maemo-mapper.c:2288
+#: ../src/display.c:280
 msgid "Real Time Kinematic"
 msgstr "Real Time Kinematic"
 
-#: ../src/maemo-mapper.c:3723
+#: ../src/path.c:919
 msgid "Really clear the track?"
 msgstr ""
 
-#: ../src/maemo-mapper.c:3678
+#: ../src/path.c:798
 msgid "Recalculating directions..."
 msgstr "Sto ricalcolando le direzioni..."
 
-#: ../src/maemo-mapper.c:2993
+#: ../src/poi.c:150
 msgid "Recreation"
 msgstr "Tempo libero"
 
-#: ../src/maemo-mapper.c:11583
+#: ../src/maps.c:1611
 msgid "Rename..."
 msgstr "Rinomina..."
 
-#: ../src/maemo-mapper.c:11440
+#: ../src/maps.c:1468
 msgid "Replace all repositories with the default repository?"
 msgstr "Sostituisco tutti i depositi con quello predefinito?"
 
-#: ../src/maemo-mapper.c:6137
+#: ../src/menu.c:1369 ../src/menu.c:1452
 msgid "Reset"
 msgstr "Reimposta"
 
-#: ../src/maemo-mapper.c:6281 ../src/maemo-mapper.c:8069
+#: ../src/main.c:278 ../src/menu.c:1585
 msgid "Reset Bluetooth"
 msgstr "Riavvia Bluetooth"
 
-#: ../src/maemo-mapper.c:4699
+#: ../src/main.c:247
+msgid "Reset Viewing Angle"
+msgstr ""
+
+#: ../src/settings.c:730
 msgid "Reset all colors to their original defaults?"
 msgstr "Reimposto tutti i colori con quelli predefiniti?"
 
-#: ../src/maemo-mapper.c:4580
+#: ../src/settings.c:616
 msgid "Reset all hardware keys to their original defaults?"
 msgstr "Reimposto tutti tasti con i valori predefiniti?"
 
-#: ../src/maemo-mapper.c:4614 ../src/maemo-mapper.c:4735
-#: ../src/maemo-mapper.c:11561
+#: ../src/maps.c:1589 ../src/settings.c:650 ../src/settings.c:766
 msgid "Reset..."
 msgstr "Reimposta..."
 
-#: ../src/maemo-mapper.c:2987
+#: ../src/poi.c:144
 msgid "Residence"
 msgstr "Residence"
 
-#: ../src/maemo-mapper.c:4777 ../src/maemo-mapper.c:6123
-#: ../src/maemo-mapper.c:6204
+#: ../src/poi.c:146
+msgid "Restaurant"
+msgstr ""
+
+#: ../src/main.c:194 ../src/menu.c:1470
+#, fuzzy
+msgid "Right"
+msgstr "Superiore destro"
+
+#: ../src/menu.c:1444
+#, fuzzy
+msgid "Rotate"
+msgstr "Rotta"
+
+#: ../src/settings.c:1097
+#, fuzzy
+msgid "Rotate Sensit."
+msgstr "Sensibilità"
+
+#: ../src/main.c:249
+msgid "Rotate View Clockwise"
+msgstr ""
+
+#: ../src/main.c:251
+msgid "Rotate View Counter-Clockwise"
+msgstr ""
+
+#: ../src/menu.c:1355 ../src/menu.c:1520 ../src/settings.c:808
 msgid "Route"
 msgstr "Rotta"
 
-#: ../src/maemo-mapper.c:10311
+#: ../src/path.c:672
 msgid "Route Downloaded"
 msgstr "Rotta scaricata"
 
-#: ../src/maemo-mapper.c:8368 ../src/maemo-mapper.c:10360
+#: ../src/main.c:485 ../src/menu.c:119
 msgid "Route Opened"
 msgstr "Rotta aperta"
 
-#: ../src/maemo-mapper.c:10615
+#: ../src/menu.c:150
 msgid "Route Saved"
 msgstr "Rotta salvata"
 
-#: ../src/maemo-mapper.c:10705
+#: ../src/menu.c:1048
 msgid "Routes are now hidden"
 msgstr "Le rotte sono nascoste"
 
-#: ../src/maemo-mapper.c:10699
+#: ../src/menu.c:1042
 msgid "Routes are now shown"
 msgstr "Le rotte sono visibili"
 
-#: ../src/maemo-mapper.c:2285
+#: ../src/display.c:277
 msgid "SPS"
 msgstr "SPS"
 
-#: ../src/maemo-mapper.c:2849
+#: ../src/display.c:841
 msgid "Sat in use"
 msgstr "Satelliti in uso"
 
-#: ../src/maemo-mapper.c:2840
+#: ../src/display.c:832
 msgid "Sat in view"
 msgstr "Satelliti in vista"
 
-#: ../src/maemo-mapper.c:2781
+#: ../src/display.c:773
 msgid "Satellites details"
 msgstr "Dettagli satelliti"
 
-#: ../src/maemo-mapper.c:2707
+#: ../src/display.c:699
 msgid "Satellites in view"
 msgstr "Satelliti in vista"
 
-#: ../src/maemo-mapper.c:6131 ../src/maemo-mapper.c:6149
+#: ../src/menu.c:1363 ../src/menu.c:1381
 msgid "Save..."
 msgstr "Salva..."
 
-#: ../src/maemo-mapper.c:6199
+#: ../src/menu.c:1510
 msgid "Scale"
 msgstr "Scala"
 
-#: ../src/maemo-mapper.c:4978
+#: ../src/settings.c:1019
 msgid "Scan..."
 msgstr "Cerca..."
 
-#: ../src/maemo-mapper.c:4495
+#: ../src/settings.c:542
 msgid "Scanning for Bluetooth Devices"
 msgstr "Sto cercando i dispositivi bluetooth"
 
-#: ../src/maemo-mapper.c:2999
+#: ../src/poi.c:156
 msgid "School"
 msgstr "Scuola"
 
-#: ../src/maemo-mapper.c:3138
+#: ../src/gps.c:790
 msgid "Searching for GPS receiver"
 msgstr "Sto cercando un ricevitore GPS"
 
-#: ../src/maemo-mapper.c:4459
+#: ../src/settings.c:506
 msgid "Select Bluetooth Device"
 msgstr "Scegli il dispositivo bluetooth"
 
-#: ../src/maemo-mapper.c:8054
+#: ../src/main.c:263
 msgid "Select Next Repository"
 msgstr "Prossimo deposito"
 
-#: ../src/maemo-mapper.c:8560
+#: ../src/poi.c:421
 msgid "Select POI"
 msgstr "Seleziona POI"
 
-#: ../src/maemo-mapper.c:8630
+#: ../src/poi.c:1933
+msgid ""
+"Select an operation to perform\n"
+"on the POIs that you checked\n"
+"in the POI list."
+msgstr ""
+
+#: ../src/poi.c:486
 msgid "Select one POI from the list."
 msgstr "Scegli un POI dalla lista."
 
-#: ../src/maemo-mapper.c:4998
-msgid "Sensitivity"
-msgstr "Sensibilità"
+#: ../src/poi.c:142
+#, fuzzy
+msgid "Service Station"
+msgstr "Tempo libero"
 
-#: ../src/maemo-mapper.c:6431
+#: ../src/poi.c:1502 ../src/poi.c:1939
+#, fuzzy
+msgid "Set Category..."
+msgstr "Modifica categorie"
+
+#: ../src/cmenu.c:614
 msgid "Set as GPS Location"
 msgstr "Usa la località del GPS"
 
-#: ../src/maemo-mapper.c:4940
+#: ../src/settings.c:980
 msgid "Settings"
 msgstr "Impostazioni"
 
-#: ../src/maemo-mapper.c:6288
+#: ../src/menu.c:1592
 msgid "Settings..."
 msgstr "Impostazioni..."
 
-#: ../src/maemo-mapper.c:12058
+#: ../src/maps.c:2059
 msgid "Setup"
 msgstr "Impostazioni"
 
-#: ../src/maemo-mapper.c:2991
+#: ../src/poi.c:148
 msgid "Shopping/Services"
 msgstr "Shopping/Servizi"
 
-#: ../src/maemo-mapper.c:6442
+#: ../src/menu.c:1501
+#, fuzzy
+msgid "Show"
+msgstr "Scuola"
+
+#: ../src/cmenu.c:625
 msgid "Show Description"
 msgstr "Mostra descrizione"
 
-#: ../src/maemo-mapper.c:6157 ../src/maemo-mapper.c:8064
+#: ../src/main.c:273 ../src/menu.c:1389
 msgid "Show Distance from Beginning"
 msgstr "Mostra la distanza dalla partenza"
 
-#: ../src/maemo-mapper.c:8062
+#: ../src/main.c:271
 msgid "Show Distance from Last Break"
 msgstr "Mostra la distanza verso l'ultima sosta"
 
-#: ../src/maemo-mapper.c:6155
+#: ../src/menu.c:1387
 msgid "Show Distance from Last Mark"
 msgstr "Mostra la distanza verso l'ultimo segnale"
 
-#: ../src/maemo-mapper.c:6418 ../src/maemo-mapper.c:6449
-#: ../src/maemo-mapper.c:6473
+#: ../src/cmenu.c:601 ../src/cmenu.c:632 ../src/cmenu.c:656
 msgid "Show Distance to"
 msgstr "Mostra la distanza verso"
 
-#: ../src/maemo-mapper.c:6135 ../src/maemo-mapper.c:8058
+#: ../src/main.c:267 ../src/menu.c:1367
 msgid "Show Distance to End of Route"
 msgstr "Mostra la distanza verso la fine della rotta"
 
-#: ../src/maemo-mapper.c:6133 ../src/maemo-mapper.c:8056
+#: ../src/main.c:265 ../src/menu.c:1365
 msgid "Show Distance to Next Waypoint"
 msgstr "Mostra la distanza verso il prossimo waypoint"
 
-#: ../src/maemo-mapper.c:6274
+#: ../src/menu.c:1578
 msgid "Show Information"
 msgstr "Mostra informazioni"
 
-#: ../src/maemo-mapper.c:6415 ../src/maemo-mapper.c:6440
+#: ../src/cmenu.c:598 ../src/cmenu.c:623
 msgid "Show Lat/Lon"
 msgstr "Mostra Lat/Lon"
 
-#: ../src/maemo-mapper.c:5196
+#: ../src/settings.c:1283
 msgid "Show POI below zoom"
 msgstr "Mostra POI con zoom"
 
-#: ../src/maemo-mapper.c:13414
+#: ../src/display.c:2416
 #, fuzzy
 msgid "Show Position"
 msgstr "Mostra descrizione"
 
-#: ../src/maemo-mapper.c:2292
+#: ../src/display.c:284
 msgid "Simulation"
 msgstr "Simulazione"
 
-#: ../src/maemo-mapper.c:10049
+#: ../src/path.c:1086 ../src/poi.c:2220
 msgid "Source URL"
 msgstr "Fonte URL"
 
-#: ../src/maemo-mapper.c:2804 ../src/maemo-mapper.c:5055
+#: ../src/menu.c:1475
+#, fuzzy
+msgid "South"
+msgstr "Scorri verso sud"
+
+#: ../src/display.c:796
 msgid "Speed"
 msgstr "Velocità"
 
-#: ../src/maemo-mapper.c:5152
+#: ../src/settings.c:1239
 msgid "Speed Limit"
 msgstr "Limite di velocità"
 
-#: ../src/maemo-mapper.c:2986
+#: ../src/poi.c:143
 msgid "Stations for purchasing fuel for vehicles."
 msgstr "Stazioni di servizio."
 
-#: ../src/maemo-mapper.c:3399
+#: ../src/maps.c:504
+msgid ""
+"The current repository is in a legacy format and will be converted.  You "
+"should delete your old maps if you no longer plan to use them."
+msgstr ""
+
+#: ../src/path.c:551
 msgid "The current route is empty."
 msgstr "La rotta corrente è vuota."
 
-#: ../src/maemo-mapper.c:3445 ../src/maemo-mapper.c:3460
+#: ../src/path.c:597 ../src/path.c:612
 msgid "The current track is empty."
 msgstr "La traccia corrente è vuota."
 
-#: ../src/maemo-mapper.c:4660
+#: ../src/settings.c:696
 msgid "The following action is mapped to multiple keys"
 msgstr "Le azioni seguenti sono mappate su tasti multipli"
 
-#: ../src/maemo-mapper.c:9002
+#: ../src/input.c:364
 msgid "There are no other next-able repositories."
 msgstr "Non ci sono altri depositi nella sequenza."
 
-#: ../src/maemo-mapper.c:13853
+#: ../src/cmenu.c:265 ../src/cmenu.c:287 ../src/cmenu.c:306 ../src/cmenu.c:326
+#: ../src/cmenu.c:345 ../src/cmenu.c:364 ../src/cmenu.c:442 ../src/cmenu.c:461
 msgid "There are no waypoints."
 msgstr "Non ci sono waypoint."
 
-#: ../src/maemo-mapper.c:3380 ../src/maemo-mapper.c:11044
+#: ../src/menu.c:912 ../src/path.c:532
 msgid "There is no next waypoint."
 msgstr "Non c'è un waypoint successivo."
 
-#: ../src/maemo-mapper.c:8046
+#: ../src/main.c:253
 msgid "Toggle Auto-Center"
 msgstr "Centro automatico"
 
-#: ../src/maemo-mapper.c:8048
+#: ../src/main.c:255
+#, fuzzy
+msgid "Toggle Auto-Rotate"
+msgstr "Centro automatico"
+
+#: ../src/main.c:257
 msgid "Toggle Fullscreen"
 msgstr "Schermo intero"
 
-#: ../src/maemo-mapper.c:8065
+#: ../src/main.c:274
 msgid "Toggle GPS"
 msgstr "Abilita GPS"
 
-#: ../src/maemo-mapper.c:8066
+#: ../src/main.c:275
 msgid "Toggle GPS Info"
 msgstr "Abilita informazioni GPS"
 
-#: ../src/maemo-mapper.c:8053
+#: ../src/main.c:262
 msgid "Toggle POIs"
 msgstr "Abilita POI"
 
-#: ../src/maemo-mapper.c:8052
+#: ../src/main.c:261
 msgid "Toggle Scale"
 msgstr "Scala"
 
-#: ../src/maemo-mapper.c:8068
+#: ../src/main.c:277
 msgid "Toggle Speed Limit"
 msgstr "Attiva/disattiva limite di velocità"
 
-#: ../src/maemo-mapper.c:8051
+#: ../src/main.c:260
 msgid "Toggle Tracks"
 msgstr "Abilita tracce"
 
-#: ../src/maemo-mapper.c:8095 ../src/maemo-mapper.c:12186
+#: ../src/main.c:304 ../src/maps.c:2187
 msgid "Top-Left"
 msgstr "Superiore sinistra"
 
-#: ../src/maemo-mapper.c:8096
+#: ../src/main.c:305
 msgid "Top-Right"
 msgstr "Superiore destro"
 
-#: ../src/maemo-mapper.c:4762 ../src/maemo-mapper.c:6143
-#: ../src/maemo-mapper.c:6209
+#: ../src/menu.c:1375 ../src/menu.c:1525 ../src/settings.c:793
 msgid "Track"
 msgstr "Percorso"
 
-#: ../src/maemo-mapper.c:10434
+#: ../src/menu.c:231
 msgid "Track Opened"
 msgstr "Percorso aperto"
 
-#: ../src/maemo-mapper.c:10456
+#: ../src/menu.c:253
 msgid "Track Saved"
 msgstr "Percorso salvato"
 
-#: ../src/maemo-mapper.c:10655
+#: ../src/menu.c:985
 msgid "Tracks are now hidden"
 msgstr "I percorsi sono nascosti"
 
-#: ../src/maemo-mapper.c:10649
+#: ../src/menu.c:979
 msgid "Tracks are now shown"
 msgstr "I percorsi sono visibili"
 
-#: ../src/maemo-mapper.c:2995
+#: ../src/poi.c:152
 msgid "Transportation"
 msgstr "Trasporti"
 
-#: ../src/maemo-mapper.c:11278
+#: ../src/maps.c:1304
 msgid "URL Format"
 msgstr "Formato URL"
 
-#: ../src/maemo-mapper.c:5543
-msgid "Unable to create cache directory for repository"
+#: ../src/maps.c:684
+#, fuzzy
+msgid "Unable to create map database for repository"
 msgstr "Impossibile creare la cartella per il deposito"
 
-#: ../src/maemo-mapper.c:5118
+#: ../src/settings.c:1162
+#, fuzzy
+msgid "Unblank Screen"
+msgstr "Schermo intero"
+
+#: ../src/settings.c:1191
 msgid "Units"
 msgstr "Unità"
 
-#: ../src/maemo-mapper.c:11003
+#: ../src/util.c:155
 msgid "Unknown error while locating address."
 msgstr ""
 
-#: ../src/maemo-mapper.c:10070
+#: ../src/main.c:193 ../src/menu.c:1464
+msgid "Up"
+msgstr ""
+
+#: ../src/path.c:1103 ../src/poi.c:2233 ../src/poi.c:2531
 msgid "Use End of Route"
 msgstr "Usa fine della rotta"
 
-#: ../src/maemo-mapper.c:10060
+#: ../src/path.c:1097 ../src/poi.c:2227 ../src/poi.c:2525
 msgid "Use GPS Location"
 msgstr "Usa la località del GPS"
 
-#: ../src/maemo-mapper.c:6214
+#: ../src/menu.c:1530
 msgid "Velocity Vector"
 msgstr "Vettore di velocità"
 
-#: ../src/maemo-mapper.c:6181
+#: ../src/menu.c:1428
 msgid "View"
 msgstr "Mostra"
 
-#: ../src/maemo-mapper.c:12167
+#: ../src/maps.c:2168
 msgid "View Center"
 msgstr "Mostra centro"
 
-#: ../src/maemo-mapper.c:11333
+#: ../src/maps.c:1361
 msgid "View Zoom Steps"
 msgstr "Mostra intervalli di zoom"
 
-#: ../src/maemo-mapper.c:6470
+#: ../src/cmenu.c:653
 msgid "View/Edit..."
 msgstr "Mostra/Modifica..."
 
-#: ../src/maemo-mapper.c:12554
+#: ../src/poi.c:508
 msgid "WARNING: All POIs in that category will also be deleted!"
 msgstr "ATTENZIONE: tutti i POI in questa categoria verranno eliminati!"
 
-#: ../src/maemo-mapper.c:6435
+#: ../src/cmenu.c:618
 msgid "Waypoint"
 msgstr "Waypoint"
 
-#: ../src/maemo-mapper.c:6579
+#: ../src/menu.c:1477
+#, fuzzy
+msgid "West"
+msgstr "Reimposta"
+
+#: ../src/display.c:1094
 msgid ""
 "You will now see a blank screen.  You can download maps using the \"Manage "
 "Maps\" menu item in the \"Maps\" menu.  Or, press OK to enable Auto-Download."
@@ -1299,72 +1570,78 @@ msgstr ""
 "\"Gestisci mappe\" nel menu \"Mappe\" oppure premi Ok per abilitare lo "
 "scaricamento automatico."
 
-#: ../src/maemo-mapper.c:12115
+#: ../src/maps.c:2116 ../src/menu.c:1434
 msgid "Zoom"
 msgstr "Zoom"
 
-#: ../src/maemo-mapper.c:6185 ../src/maemo-mapper.c:8049
+#: ../src/main.c:258 ../src/menu.c:1438
 msgid "Zoom In"
 msgstr "Ingrandisci"
 
-#: ../src/maemo-mapper.c:6194
+#: ../src/menu.c:1505
 #, fuzzy
 msgid "Zoom Level"
 msgstr "Zoom al livello"
 
-#: ../src/maemo-mapper.c:12121
+#: ../src/maps.c:2122
 msgid "Zoom Levels to Download: (0 = most detail)"
 msgstr "Livelli di Zoom da scaricare: (0 = massimo dettaglio)"
 
-#: ../src/maemo-mapper.c:6187 ../src/maemo-mapper.c:8050
+#: ../src/main.c:259 ../src/menu.c:1440
 msgid "Zoom Out"
 msgstr "Riduci"
 
-#: ../src/maemo-mapper.c:8815 ../src/maemo-mapper.c:8928
-#: ../src/maemo-mapper.c:12356 ../src/maemo-mapper.c:12374
+#: ../src/input.c:103 ../src/input.c:290 ../src/menu.c:546 ../src/menu.c:564
 msgid "Zoom to Level"
 msgstr "Zoom al livello"
 
-#: ../src/maemo-mapper.c:11890 ../src/maemo-mapper.c:11897
+#: ../src/maps.c:1880 ../src/maps.c:1887
 msgid "about"
 msgstr "circa"
 
-#: ../src/maemo-mapper.c:2708
+#: ../src/display.c:700
 msgid "in use"
 msgstr "in uso"
 
-#: ../src/maemo-mapper.c:7999
+#: ../src/main.c:189
 msgid "km"
 msgstr "km"
 
-#: ../src/maemo-mapper.c:11810 ../src/maemo-mapper.c:11898
+#: ../src/maps.c:1791 ../src/maps.c:1888
 msgid "maps"
 msgstr "mappe"
 
-#: ../src/maemo-mapper.c:11804 ../src/maemo-mapper.c:11891
+#: ../src/maps.c:1785 ../src/maps.c:1881
 msgid "maps "
 msgstr "mappe"
 
-#: ../src/maemo-mapper.c:8000
+#: ../src/display.c:1466
+msgid "maps failed to download."
+msgstr ""
+
+#: ../src/main.c:190
 msgid "mi."
 msgstr "mi."
 
-#: ../src/maemo-mapper.c:8001
+#: ../src/main.c:191
 msgid "n.m."
 msgstr "n.m."
 
-#: ../src/maemo-mapper.c:2862
+#: ../src/display.c:854
 msgid "nofix"
 msgstr "nofix"
 
-#: ../src/maemo-mapper.c:2293 ../src/maemo-mapper.c:2871
+#: ../src/display.c:285 ../src/display.c:863
 msgid "none"
 msgstr "nessuna"
 
-#: ../src/maemo-mapper.c:11810 ../src/maemo-mapper.c:11898
+#: ../src/maps.c:1791 ../src/maps.c:1888
 msgid "up to about"
 msgstr "fino a circa"
 
+#~ msgid "Add"
+#~ msgstr "Aggiungi"
+
 #~ msgid "Category List"
 #~ msgstr "Elenco categorie"
 
@@ -1387,18 +1664,43 @@ msgstr "fino a circa"
 #~ msgid "Defaults"
 #~ msgstr "Default"
 
+#~ msgid "Delete"
+#~ msgstr "Elimina"
+
 #~ msgid "Desc."
 #~ msgstr "Descr."
 
 #~ msgid "Desc.: "
 #~ msgstr "Descr.: "
 
+#~ msgid "Dining"
+#~ msgstr "Ristorazione"
+
 #~ msgid "Distance to Location"
 #~ msgstr "Distanza per la località"
 
+#~ msgid "Downloading maps"
+#~ msgstr "Scaricamento mappe in corso"
+
+#~ msgid "Edit"
+#~ msgstr "Modifica"
+
+#~ msgid ""
+#~ "Error in download.  Check internet connection and/or Map Repository URL "
+#~ "Format."
+#~ msgstr ""
+#~ "Errore nello scaricamento. Controlla la connessione a internet e/o  l'URL "
+#~ "del deposito."
+
 #~ msgid "Escape Key"
 #~ msgstr "Tasto ESC"
 
+#~ msgid "Fuel"
+#~ msgstr "Carburante"
+
+#~ msgid "Keep Display On Only in Fullscreen Mode"
+#~ msgstr "Mantieni lo schermo sempre acceso solo quando full-screen"
+
 #~ msgid "Label: "
 #~ msgstr "Etichetta"
 
@@ -1414,6 +1716,20 @@ msgstr "fino a circa"
 #~ msgid "No waypoints found."
 #~ msgstr "Non ci sono waypoint visibili."
 
+#~ msgid ""
+#~ "Note: You can enter a device path\n"
+#~ "(e.g. \"/dev/rfcomm0\")."
+#~ msgstr ""
+#~ "Nota: puoi inserire un percorso al dispositivo\n"
+#~ "(es.   \"/dev/rfcomm0\")."
+
+#  This word refers to Pitch as in of a person's voice.
+#~ msgid "Pitch"
+#~ msgstr "Intonazione"
+
+#~ msgid "Please specify a name for the POI."
+#~ msgstr "Specifica un nome per il POI."
+
 #~ msgid "Repositories"
 #~ msgstr "Depositi"
 
index cbced0b4f08f0dbe389de73ef2bcfde52d1a8942..4a4d9afbf2d24a1c619ba2fb1931eaebebc6d11e 100644 (file)
@@ -11,7 +11,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: maemo-mapper 1.0.2\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-07-07 20:45-0400\n"
+"POT-Creation-Date: 2007-11-01 15:35-0400\n"
 "PO-Revision-Date: 2006-07-04 09:56+0200\n"
 "Last-Translator: Mischa Molhoek <mischamolhoek@gmail.com>\n"
 "Language-Team: John Costigan <gnuite@gmail.com>\n"
@@ -19,81 +19,81 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: ../src/maemo-mapper.c:12960
+#: ../src/poi.c:922
 msgid "# POIs"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6293
+#: ../src/menu.c:1597
 #, fuzzy
 msgid "About..."
 msgstr "Route"
 
-#: ../src/maemo-mapper.c:12916
-msgid "Add"
-msgstr ""
-
-#: ../src/maemo-mapper.c:12650
+#: ../src/poi.c:604
 msgid "Add Category"
 msgstr ""
 
-#: ../src/maemo-mapper.c:13149
+#: ../src/poi.c:1123
 msgid "Add POI"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6427 ../src/maemo-mapper.c:6456
+#: ../src/cmenu.c:610 ../src/cmenu.c:639
 msgid "Add POI..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:6423 ../src/maemo-mapper.c:6478
+#: ../src/cmenu.c:606 ../src/cmenu.c:661
 msgid "Add Route Point"
 msgstr ""
 
-#: ../src/maemo-mapper.c:13601
+#: ../src/path.c:1334
 #, fuzzy
 msgid "Add Waypoint"
 msgstr "Route Markering"
 
-#: ../src/maemo-mapper.c:6425 ../src/maemo-mapper.c:6480
+#: ../src/cmenu.c:608 ../src/cmenu.c:663
 #, fuzzy
 msgid "Add Waypoint..."
 msgstr "Route Markering..."
 
-#: ../src/maemo-mapper.c:10910
+#: ../src/poi.c:878
+msgid "Add..."
+msgstr ""
+
+#: ../src/menu.c:837
 msgid "Address"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10987
+#: ../src/menu.c:862
 msgid "Address Located"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6256
+#: ../src/menu.c:1489
 msgid "Address..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:5029
+#: ../src/settings.c:1126
 msgid "Advance Notice"
 msgstr "Aankondiging"
 
-#: ../src/maemo-mapper.c:12100
+#: ../src/maps.c:2101
 msgid "Along Route - Radius (tiles):"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2813
+#: ../src/display.c:805
 #, fuzzy
 msgid "Altitude"
 msgstr "Breedtegraad"
 
-#: ../src/maemo-mapper.c:4501
+#: ../src/settings.c:548
 msgid "An error occurred while attempting to scan for bluetooth devices."
 msgstr ""
 
-#: ../src/maemo-mapper.c:11489
+#: ../src/maps.c:1517
 msgid ""
 "An error occurred while retrieving the repositories.  The web service may be "
 "temporarily down."
 msgstr ""
 
-#: ../src/maemo-mapper.c:8829
+#: ../src/gps.c:955
 msgid ""
 "An error occurred while trying to reset the bluetooth radio.\n"
 "\n"
@@ -101,632 +101,798 @@ msgid ""
 "the /etc/sudoers file?"
 msgstr ""
 
-#: ../src/maemo-mapper.c:5025
+#: ../src/settings.c:1122
 msgid "Announce"
 msgstr "Aankondigen"
 
-#: ../src/maemo-mapper.c:12137
+#: ../src/maps.c:2138
 msgid "Area"
 msgstr "Gebied"
 
-#: ../src/maemo-mapper.c:4994 ../src/maemo-mapper.c:6227
+#: ../src/menu.c:1540 ../src/settings.c:1061
 msgid "Auto-Center"
 msgstr "Automatisch-Centreren"
 
-#: ../src/maemo-mapper.c:10774
+#: ../src/menu.c:1114
 msgid "Auto-Center Mode: Lat/Lon"
 msgstr "Automatisch-Centreren Mode: Lengtegr/Breedtegr"
 
-#: ../src/maemo-mapper.c:10759
+#: ../src/menu.c:1097
 msgid "Auto-Center Mode: Lead"
 msgstr "Automatisch-Centreren Mode: Lead"
 
-#: ../src/maemo-mapper.c:10788
+#: ../src/menu.c:1130
 msgid "Auto-Center Off"
 msgstr "Automatisch-Centreren Uit"
 
-#: ../src/maemo-mapper.c:6172
+#: ../src/menu.c:1419
 msgid "Auto-Download"
 msgstr "Automatisch-Downloaden"
 
-#: ../src/maemo-mapper.c:10064
+#: ../src/settings.c:1221
+#, fuzzy
+msgid "Auto-Download Pre-cache"
+msgstr "Automatisch-Downloaden"
+
+#: ../src/menu.c:1454
+#, fuzzy
+msgid "Auto-Rotate"
+msgstr "Automatisch-Updaten"
+
+#: ../src/menu.c:624
+msgid "Auto-Rotate Disabled"
+msgstr ""
+
+#: ../src/menu.c:619
+msgid "Auto-Rotate Enabled"
+msgstr ""
+
+#: ../src/path.c:1113
 msgid "Auto-Update"
 msgstr "Automatisch-Updaten"
 
-#: ../src/maemo-mapper.c:10076
+#: ../src/path.c:1119
 msgid "Avoid Highways"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8098
+#: ../src/poi.c:1749
+#, fuzzy
+msgid "Bear."
+msgstr "Opschonen"
+
+#: ../src/main.c:310
+msgid "Bluetooth"
+msgstr ""
+
+#: ../src/main.c:307
 #, fuzzy
 msgid "Bottom-Left"
 msgstr "Rechts-onder"
 
-#: ../src/maemo-mapper.c:8097 ../src/maemo-mapper.c:12208
+#: ../src/main.c:306 ../src/maps.c:2209
 msgid "Bottom-Right"
 msgstr "Rechts-onder"
 
-#: ../src/maemo-mapper.c:3767
+#: ../src/path.c:967
 msgid "Break already inserted."
 msgstr ""
 
-#: ../src/maemo-mapper.c:5191 ../src/maemo-mapper.c:11297
+#: ../src/poi.c:2509
+#, fuzzy
+msgid "Browse POIs"
+msgstr "Activeer GPS"
+
+#: ../src/maps.c:1323 ../src/menu.c:1403 ../src/settings.c:1054
+#: ../src/settings.c:1278
 msgid "Browse..."
 msgstr "Blader..."
 
-#: ../src/maemo-mapper.c:2996
+#: ../src/poi.c:153
 msgid "Bus stops, airports, train stations, etc."
 msgstr ""
 
-#: ../src/maemo-mapper.c:3001
+#: ../src/poi.c:158
 msgid "Business"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12091
+#: ../src/maps.c:2092
 msgid "By Area (see tab)"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11287
-msgid "Cache Dir."
+#: ../src/maps.c:1313
+msgid "Cache DB"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11227
+#: ../src/maps.c:1253
 msgid ""
 "Cannot delete the last repository - there must be at lease one repository."
 msgstr ""
 
-#: ../src/maemo-mapper.c:12416
+#: ../src/menu.c:1177
+#, fuzzy
 msgid ""
-"Cannot enable GPS until a GPS Receiver MAC is set in the Settings dialog box."
+"Cannot enable GPS until a GPS receiver is set up in the Settings dialog box."
 msgstr ""
 "Kan GPS niet aanzetten totdat GPS MAC adres is ingevoerd in het Configuratie "
 "scherm"
 
-#: ../src/maemo-mapper.c:8597 ../src/maemo-mapper.c:13185
+#: ../src/menu.c:1405
+#, fuzzy
+msgid "Categories..."
+msgstr "POI Categories..."
+
+#: ../src/poi.c:458 ../src/poi.c:1159 ../src/poi.c:1512 ../src/poi.c:1732
+#: ../src/poi.c:2089 ../src/poi.c:2243 ../src/poi.c:2540
 msgid "Category"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6139 ../src/maemo-mapper.c:6159
-#: ../src/maemo-mapper.c:12044
+#: ../src/poi.c:1928 ../src/poi.c:2003
+msgid "Checked POI Actions..."
+msgstr ""
+
+#: ../src/maps.c:2045 ../src/menu.c:1371 ../src/menu.c:1391
 msgid "Clear"
 msgstr "Opschonen"
 
-#: ../src/maemo-mapper.c:8060
+#: ../src/main.c:269
 #, fuzzy
 msgid "Clear Track"
 msgstr "Opschonen"
 
-#: ../src/maemo-mapper.c:6295
+#: ../src/menu.c:1448
+#, fuzzy
+msgid "Clockwise"
+msgstr "Sluiten"
+
+#: ../src/menu.c:1599
 msgid "Close"
 msgstr "Sluiten"
 
-#: ../src/maemo-mapper.c:4729
+#: ../src/settings.c:760
 #, fuzzy
 msgid "Colors"
 msgstr "Sluiten"
 
-#: ../src/maemo-mapper.c:4953
+#: ../src/settings.c:993
 #, fuzzy
 msgid "Colors..."
 msgstr "Download..."
 
-#: ../src/maemo-mapper.c:11803 ../src/maemo-mapper.c:11890
+#: ../src/menu.c:1515
+msgid "Compass Rose"
+msgstr ""
+
+#: ../src/maps.c:1784 ../src/maps.c:1880
 msgid "Confirm DELETION of"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11234
+#: ../src/maps.c:1260
 msgid "Confirm delete of repository"
 msgstr ""
 
-#: ../src/maemo-mapper.c:13966
+#: ../src/cmenu.c:385
 msgid "Confirm delete of waypoint"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11809 ../src/maemo-mapper.c:11896
+#: ../src/maps.c:1790 ../src/maps.c:1886
 msgid "Confirm download of"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4663
+#: ../src/settings.c:699
 msgid "Continue?"
 msgstr ""
 
-#: ../src/maemo-mapper.c:13451
+#: ../src/display.c:2453
 msgid "Copy"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6446
+#: ../src/cmenu.c:629
 #, fuzzy
 msgid "Copy Description"
 msgstr "Bestemming"
 
-#: ../src/maemo-mapper.c:6444
+#: ../src/cmenu.c:627
 #, fuzzy
 msgid "Copy Lat/Lon"
 msgstr "Breedte/Lengtegraad"
 
-#: ../src/maemo-mapper.c:13684
+#: ../src/menu.c:1450
+msgid "Counter"
+msgstr ""
+
+#: ../src/path.c:1417
 msgid ""
 "Creating a \"waypoint\" with no description actually adds a break point.  Is "
 "that what you want?"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2286
+#: ../src/display.c:278
 #, fuzzy
 msgid "DGPS"
 msgstr "GPS"
 
-#: ../src/maemo-mapper.c:5129
-msgid "Degrees Format"
-msgstr ""
+#: ../src/poi.c:2079
+#, fuzzy
+msgid "Default Category"
+msgstr "Category: "
 
-#: ../src/maemo-mapper.c:12631 ../src/maemo-mapper.c:13124
-msgid "Delete"
+#: ../src/settings.c:1208
+msgid "Degrees Format"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12081
+#: ../src/maps.c:2082
 msgid "Delete Maps"
 msgstr ""
 
-#: ../src/maemo-mapper.c:13008
+#: ../src/poi.c:958
 msgid "Delete POI?"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12552
+#: ../src/poi.c:506
 msgid "Delete category?"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6453 ../src/maemo-mapper.c:11586
+#: ../src/poi.c:1843
+msgid "Delete selected POI?"
+msgstr ""
+
+#: ../src/cmenu.c:636 ../src/maps.c:1614 ../src/poi.c:585 ../src/poi.c:1096
+#: ../src/poi.c:1943
 msgid "Delete..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:4489 ../src/maemo-mapper.c:10513
-#: ../src/maemo-mapper.c:12669 ../src/maemo-mapper.c:12955
-#: ../src/maemo-mapper.c:13212 ../src/maemo-mapper.c:13626
+#: ../src/menu.c:310 ../src/path.c:1359 ../src/poi.c:623 ../src/poi.c:917
+#: ../src/poi.c:1174 ../src/settings.c:536
 #, fuzzy
 msgid "Description"
 msgstr "Bestemming"
 
-#: ../src/maemo-mapper.c:10093
+#: ../src/path.c:1136
 msgid "Destination"
 msgstr "Bestemming"
 
-#: ../src/maemo-mapper.c:6278
+#: ../src/menu.c:1582
 #, fuzzy
 msgid "Details..."
 msgstr "Instellingen..."
 
-#: ../src/maemo-mapper.c:2989
-msgid "Dining"
-msgstr ""
+#: ../src/gps.c:779
+#, fuzzy
+msgid "Disconnecting from GPS receiver"
+msgstr "Er wordt naar GPS ontvanger gezocht"
 
-#: ../src/maemo-mapper.c:3365 ../src/maemo-mapper.c:3425
-#: ../src/maemo-mapper.c:13566
+#: ../src/poi.c:1740
+#, fuzzy
+msgid "Dist."
+msgstr "Show Distance to"
+
+#: ../src/cmenu.c:136 ../src/path.c:517 ../src/path.c:577
 #, fuzzy
 msgid "Distance"
 msgstr "Show Distance to"
 
-#: ../src/maemo-mapper.c:11354
+#: ../src/maps.c:1382
 msgid "Double Pixels"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12068
+#: ../src/main.c:195 ../src/menu.c:1466
+msgid "Down"
+msgstr ""
+
+#: ../src/maps.c:2069
 #, fuzzy
 msgid "Download Maps"
 msgstr "Landkaarten worden gedownload"
 
-#: ../src/maemo-mapper.c:10034
+#: ../src/poi.c:2202
+#, fuzzy
+msgid "Download POIs"
+msgstr "Landkaarten worden gedownload"
+
+#: ../src/path.c:1071
 msgid "Download Route"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6420 ../src/maemo-mapper.c:6451
-#: ../src/maemo-mapper.c:6475
+#: ../src/cmenu.c:603 ../src/cmenu.c:634 ../src/cmenu.c:658
 msgid "Download Route to..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:11317
+#: ../src/maps.c:1345
 #, fuzzy
 msgid "Download Zoom Steps"
 msgstr "Download Route"
 
-#: ../src/maemo-mapper.c:6129 ../src/maemo-mapper.c:11567
+#: ../src/maps.c:1595 ../src/menu.c:1361 ../src/menu.c:1401
 msgid "Download..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:6937
-msgid "Downloading maps"
-msgstr "Landkaarten worden gedownload"
+#: ../src/maps.c:654 ../src/maps.c:667
+msgid "Downloaded maps will not be cached."
+msgstr ""
 
-#: ../src/maemo-mapper.c:12913
-msgid "Edit"
+#: ../src/menu.c:1479
+msgid "East"
 msgstr ""
 
-#: ../src/maemo-mapper.c:13208
+#: ../src/poi.c:1170
 msgid "Edit Categories..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:12625
+#: ../src/poi.c:579
 msgid "Edit Category"
 msgstr ""
 
-#: ../src/maemo-mapper.c:13118
+#: ../src/poi.c:1090
 msgid "Edit POI"
 msgstr ""
 
-#: ../src/maemo-mapper.c:3000
+#: ../src/poi.c:875 ../src/poi.c:1999
+msgid "Edit..."
+msgstr ""
+
+#: ../src/poi.c:157
 msgid "Elementary schools, college campuses, etc."
 msgstr ""
 
-#: ../src/maemo-mapper.c:6270
+#: ../src/menu.c:1574
 msgid "Enable GPS"
 msgstr "Activeer GPS"
 
-#: ../src/maemo-mapper.c:5042
+#: ../src/settings.c:1139
 msgid "Enable Voice Synthesis (requires flite)"
 msgstr "Activeer Spraak (heeft geinstallerde flite nodig)"
 
-#: ../src/maemo-mapper.c:12693 ../src/maemo-mapper.c:12945
+#: ../src/poi.c:647 ../src/poi.c:907
 #, fuzzy
 msgid "Enabled"
 msgstr "Activeer GPS"
 
-#: ../src/maemo-mapper.c:7185
-msgid ""
-"Error in download.  Check internet connection and/or Map Repository URL "
-"Format."
+#: ../src/poi.c:1305
+#, fuzzy
+msgid "Error adding POI"
+msgstr "Fout by verwerken GPX bestand."
+
+#: ../src/poi.c:710
+#, fuzzy
+msgid "Error adding category"
+msgstr "Fout by verwerken GPX bestand."
+
+#: ../src/gps.c:631
+#, fuzzy
+msgid "Error connecting to GPS receiver."
+msgstr "Failed to connect to GPX Directions server"
+
+#: ../src/gps.c:617
+msgid "Error connecting to GPSD."
+msgstr ""
+
+#: ../src/poi.c:521 ../src/poi.c:969 ../src/poi.c:1871
+msgid "Error deleting POI"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8371 ../src/maemo-mapper.c:10319
-#: ../src/maemo-mapper.c:10363 ../src/maemo-mapper.c:10437
+#: ../src/poi.c:530
+#, fuzzy
+msgid "Error deleting category"
+msgstr "Fout bij schrijven GPX bestand."
+
+#: ../src/main.c:488 ../src/menu.c:122 ../src/menu.c:234 ../src/path.c:678
+#: ../src/poi.c:2130 ../src/poi.c:2481
 msgid "Error parsing GPX file."
 msgstr "Fout by verwerken GPX bestand."
 
-#: ../src/maemo-mapper.c:1501
+#: ../src/gps.c:667
+#, fuzzy
+msgid "Error reading GPS data."
+msgstr "Fout by verwerken GPX bestand."
+
+#: ../src/poi.c:754
+msgid "Error updating Category"
+msgstr ""
+
+#: ../src/poi.c:1285 ../src/poi.c:1583
+#, fuzzy
+msgid "Error updating POI"
+msgstr "Fout by verwerken GPX bestand."
+
+#: ../src/poi.c:695
+msgid "Error updating category"
+msgstr ""
+
+#: ../src/gpx.c:478 ../src/gpx.c:805
 #, fuzzy
 msgid "Error while writing to file"
 msgstr "Fout bij schrijven GPX bestand."
 
-#: ../src/maemo-mapper.c:10459 ../src/maemo-mapper.c:10618
+#: ../src/poi.c:103
+#, fuzzy
+msgid "Error with POI database"
+msgstr "Fout by verwerken GPX bestand."
+
+#: ../src/menu.c:153 ../src/menu.c:256 ../src/poi.c:1911
 msgid "Error writing GPX file."
 msgstr "Fout bij schrijven GPX bestand."
 
-#: ../src/maemo-mapper.c:3148
+#: ../src/gps.c:801
 msgid "Establishing GPS fix"
 msgstr "GPS zoekt satellieten"
 
-#: ../src/maemo-mapper.c:2290
+#: ../src/display.c:282
 msgid "Estimated"
 msgstr ""
 
-#: ../src/maemo-mapper.c:3903
+#: ../src/poi.c:1948
+msgid "Export to GPX..."
+msgstr ""
+
+#: ../src/gps.c:923
 #, fuzzy
-msgid "Failed to connect to GPS receiver.  Retry?"
+msgid "Failed to connect to Bluetooth GPS receiver."
 msgstr "Failed to connect to GPX Directions server"
 
-#: ../src/maemo-mapper.c:10251 ../src/maemo-mapper.c:10957
+#: ../src/util.c:139
 msgid "Failed to connect to GPX Directions server"
 msgstr ""
 
-#: ../src/maemo-mapper.c:5577
+#: ../src/settings.c:1646
 msgid "Failed to initialize GConf.  Quitting."
 msgstr "initialiseren GConf mislukt.  Programma wordt afgesloten."
 
-#: ../src/maemo-mapper.c:4047
+#: ../src/settings.c:72
 msgid "Failed to initialize GConf.  Settings were not saved."
 msgstr "initialiseren GConf mislukt.  Instellingen niet opgeslagen."
 
-#: ../src/maemo-mapper.c:7750 ../src/maemo-mapper.c:8360
+#: ../src/display.c:2561 ../src/main.c:476
 msgid "Failed to open file for reading"
 msgstr ""
 
-#: ../src/maemo-mapper.c:7403 ../src/maemo-mapper.c:7751
+#: ../src/display.c:2562
 msgid "Failed to open file for writing"
 msgstr ""
 
-#: ../src/maemo-mapper.c:3014
+#: ../src/maps.c:652 ../src/maps.c:666
+msgid "Failed to open map database for repository"
+msgstr ""
+
+#: ../src/poi.c:171
 msgid "Failed to open or create database"
 msgstr ""
 
-#: ../src/maemo-mapper.c:1502
+#: ../src/path.c:1553
+msgid "Failed to open path database. Tracks and routes will not be saved."
+msgstr ""
+
+#: ../src/path.c:195 ../src/path.c:221 ../src/path.c:240
+msgid "Failed to write to path database. Tracks and routes may not be saved."
+msgstr ""
+
+#: ../src/main.c:312
+msgid "File"
+msgstr ""
+
+#: ../src/settings.c:1044
+msgid "File Path"
+msgstr ""
+
+#: ../src/gpx.c:479 ../src/gpx.c:806
 msgid "File is incomplete."
 msgstr ""
 
-#: ../src/maemo-mapper.c:2858
+#: ../src/display.c:850
 msgid "Fix"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2867
+#: ../src/display.c:859
 msgid "Fix Quality"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2289
+#: ../src/settings.c:1093
+msgid "Fixed"
+msgstr ""
+
+#: ../src/display.c:281
 msgid "Float RTK"
 msgstr ""
 
-#: ../src/maemo-mapper.c:13442
+#: ../src/display.c:2444
 #, fuzzy
 msgid "Format"
 msgstr "URI Formaat"
 
-#: ../src/maemo-mapper.c:2985
-msgid "Fuel"
-msgstr ""
-
-#: ../src/maemo-mapper.c:6189
+#: ../src/menu.c:1564
 msgid "Full Screen"
 msgstr "Volledig Scherm"
 
-#: ../src/maemo-mapper.c:4747 ../src/maemo-mapper.c:4964
-#: ../src/maemo-mapper.c:6266
+#: ../src/menu.c:1570 ../src/settings.c:778 ../src/settings.c:1004
 msgid "GPS"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2761
+#: ../src/display.c:753
 msgid "GPS Details"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2774
+#: ../src/display.c:766
 #, fuzzy
 msgid "GPS Information"
 msgstr "GPS Locatie"
 
-#: ../src/maemo-mapper.c:6258 ../src/maemo-mapper.c:12151
+#: ../src/maps.c:2152 ../src/menu.c:1491
 msgid "GPS Location"
 msgstr "GPS Locatie"
 
-#: ../src/maemo-mapper.c:3004
+#: ../src/main.c:311
+#, fuzzy
+msgid "GPSD"
+msgstr "GPS"
+
+#: ../src/settings.c:1025
+msgid "GPSD Host"
+msgstr ""
+
+#: ../src/poi.c:161
 msgid "General landmarks."
 msgstr ""
 
-#: ../src/maemo-mapper.c:3002
+#: ../src/poi.c:159
 msgid "General places of business."
 msgstr ""
 
-#: ../src/maemo-mapper.c:6250
+#: ../src/menu.c:1483 ../src/poi.c:1996
 msgid "Go to"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10900
+#: ../src/menu.c:827
 msgid "Go to Address"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10806
+#: ../src/menu.c:731
 #, fuzzy
 msgid "Go to Lat/Lon"
 msgstr "Breedte/Lengtegraad"
 
-#: ../src/maemo-mapper.c:6483
+#: ../src/cmenu.c:666
 msgid "Go to Nearest"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6460
+#: ../src/cmenu.c:643
 msgid "Go to Next"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4608
+#: ../src/settings.c:644
 msgid "Hardware Keys"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4950
+#: ../src/settings.c:990
 msgid "Hardware Keys..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:2822
+#: ../src/display.c:814
 msgid "Heading"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6291
+#: ../src/menu.c:1595
 #, fuzzy
 msgid "Help..."
 msgstr "Open..."
 
-#: ../src/maemo-mapper.c:2988
+#: ../src/poi.c:145
 msgid "Houses, apartments, or other residences of import."
 msgstr ""
 
-#: ../src/maemo-mapper.c:12937
+#: ../src/poi.c:899
 msgid "ID"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2994
+#: ../src/menu.c:1399
+msgid "Import..."
+msgstr ""
+
+#: ../src/poi.c:151
 msgid "Indoor or Outdoor places to have fun."
 msgstr ""
 
-#: ../src/maemo-mapper.c:5102
+#: ../src/settings.c:1174
 #, fuzzy
-msgid "Information Font Size"
+msgid "Info Font Size"
 msgstr "GPS Locatie"
 
-#: ../src/maemo-mapper.c:6151
+#: ../src/menu.c:1383
 #, fuzzy
 msgid "Insert Break"
 msgstr "Insert Breakpoint"
 
-#: ../src/maemo-mapper.c:10493
+#: ../src/menu.c:290
 #, fuzzy
 msgid "Insert Mark"
 msgstr "Insert Breakpoint"
 
-#: ../src/maemo-mapper.c:6153
+#: ../src/menu.c:1385
 #, fuzzy
 msgid "Insert Mark..."
 msgstr "Insert Breakpoint"
 
-#: ../src/maemo-mapper.c:8059
+#: ../src/main.c:268
 #, fuzzy
 msgid "Insert Track Break"
 msgstr "Insert Breakpoint"
 
-#: ../src/maemo-mapper.c:12324
+#: ../src/maps.c:2342
 msgid "Invalid Bottom-Right Latitude"
 msgstr "Ongeldige Rechts-Onder Breedtegraad"
 
-#: ../src/maemo-mapper.c:12331
+#: ../src/maps.c:2349
 msgid "Invalid Bottom-Right Longitude"
 msgstr "Ongeldige Rechts-Onder Lengtegraad"
 
-#: ../src/maemo-mapper.c:10865 ../src/maemo-mapper.c:13267
+#: ../src/menu.c:792 ../src/poi.c:1224
 #, fuzzy
 msgid "Invalid Latitude"
 msgstr "Ongeldige Links-Boven Breedtegraad"
 
-#: ../src/maemo-mapper.c:10872 ../src/maemo-mapper.c:13274
+#: ../src/menu.c:799 ../src/poi.c:1231
 #, fuzzy
 msgid "Invalid Longitude"
 msgstr "Ongeldige Links-Boven Lengtegraad"
 
-#: ../src/maemo-mapper.c:9534 ../src/maemo-mapper.c:9545
+#: ../src/gps.c:66 ../src/gps.c:77
 msgid "Invalid NMEA input from receiver!"
 msgstr "Ongeldige NMEA invoer van ontvanger!"
 
-#: ../src/maemo-mapper.c:12310
+#: ../src/maps.c:2328
 msgid "Invalid Top-Left Latitude"
 msgstr "Ongeldige Links-Boven Breedtegraad"
 
-#: ../src/maemo-mapper.c:12317
+#: ../src/maps.c:2335
 msgid "Invalid Top-Left Longitude"
 msgstr "Ongeldige Links-Boven Lengtegraad"
 
-#: ../src/maemo-mapper.c:10971
+#: ../src/util.c:150
 #, fuzzy
 msgid "Invalid address."
 msgstr "Ongeldige Links-Boven Breedtegraad"
 
-#: ../src/maemo-mapper.c:10264
+#: ../src/poi.c:2460
+#, fuzzy
+msgid "Invalid origin or query."
+msgstr "Ongeldige Links-Boven Lengtegraad"
+
+#: ../src/path.c:657
 msgid "Invalid source or destination."
 msgstr ""
 
-#: ../src/maemo-mapper.c:6562
+#: ../src/display.c:1077
 msgid ""
 "It looks like this is your first time running Maemo Mapper.  Press OK to "
 "view the the help pages. Otherwise, press Cancel to continue."
 msgstr ""
 
-#: ../src/maemo-mapper.c:5094
-msgid "Keep Display On Only in Fullscreen Mode"
-msgstr "Hou het display alleen aan in volledig scherm mode"
-
-#: ../src/maemo-mapper.c:8592 ../src/maemo-mapper.c:12661
-#: ../src/maemo-mapper.c:12950 ../src/maemo-mapper.c:13177
+#: ../src/poi.c:453 ../src/poi.c:615 ../src/poi.c:912 ../src/poi.c:1151
+#: ../src/poi.c:1757
 msgid "Label"
 msgstr ""
 
-#: ../src/maemo-mapper.c:3003
+#: ../src/poi.c:160
 msgid "Landmark"
 msgstr ""
 
-#: ../src/maemo-mapper.c:13161 ../src/maemo-mapper.c:13424
+#: ../src/display.c:2426 ../src/poi.c:1135
 #, fuzzy
 msgid "Lat"
 msgstr "Breedte/Lengtegraad"
 
-#: ../src/maemo-mapper.c:10503 ../src/maemo-mapper.c:13611
+#: ../src/menu.c:300 ../src/path.c:1344
 #, fuzzy
 msgid "Lat, Lon:"
 msgstr "Breedte/Lengtegraad"
 
-#: ../src/maemo-mapper.c:6231
+#: ../src/menu.c:1544
 msgid "Lat/Lon"
 msgstr "Breedte/Lengtegraad"
 
-#: ../src/maemo-mapper.c:6254
+#: ../src/menu.c:1487
 #, fuzzy
 msgid "Lat/Lon..."
 msgstr "Breedte/Lengtegraad"
 
-#: ../src/maemo-mapper.c:2786 ../src/maemo-mapper.c:10816
-#: ../src/maemo-mapper.c:12141 ../src/maemo-mapper.c:13512
+#: ../src/cmenu.c:82 ../src/display.c:778 ../src/maps.c:2142 ../src/menu.c:741
 msgid "Latitude"
 msgstr "Breedtegraad"
 
-#: ../src/maemo-mapper.c:6237
+#: ../src/menu.c:1550
 msgid "Lead"
 msgstr "Vooraf"
 
-#: ../src/maemo-mapper.c:5011
+#: ../src/settings.c:1078
 msgid "Lead Amount"
 msgstr "Hoeveel Vooraf"
 
-#: ../src/maemo-mapper.c:5082
+#: ../src/main.c:196 ../src/menu.c:1468
+#, fuzzy
+msgid "Left"
+msgstr "Links-Boven"
+
+#: ../src/settings.c:1151
 msgid "Line Width"
 msgstr "Lijn Breedte"
 
-#: ../src/maemo-mapper.c:2831
+#: ../src/display.c:823
 msgid "Local time"
 msgstr ""
 
-#: ../src/maemo-mapper.c:5162 ../src/maemo-mapper.c:6409
-#: ../src/maemo-mapper.c:8587
+#: ../src/cmenu.c:592 ../src/poi.c:448 ../src/settings.c:1249
 #, fuzzy
 msgid "Location"
 msgstr "GPS Locatie"
 
-#: ../src/maemo-mapper.c:2997
+#: ../src/poi.c:154
 msgid "Lodging"
 msgstr ""
 
-#: ../src/maemo-mapper.c:13169 ../src/maemo-mapper.c:13433
+#: ../src/display.c:2435 ../src/poi.c:1143
 #, fuzzy
 msgid "Lon"
 msgstr "Breedte/Lengtegraad"
 
-#: ../src/maemo-mapper.c:2795 ../src/maemo-mapper.c:10829
-#: ../src/maemo-mapper.c:12145 ../src/maemo-mapper.c:13513
+#: ../src/cmenu.c:83 ../src/display.c:787 ../src/maps.c:2146 ../src/menu.c:755
 msgid "Longitude"
 msgstr "Lengtegraad"
 
-#: ../src/maemo-mapper.c:4484 ../src/maemo-mapper.c:4968
+#: ../src/settings.c:531
 msgid "MAC"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11470
+#: ../src/settings.c:1009
+msgid "MAC Address"
+msgstr ""
+
+#: ../src/maps.c:1498
 msgid ""
 "Maemo Mapper will now download and add a list of possibly-duplicate "
 "repositories from the internet.  Continue?"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12033
+#: ../src/maps.c:2034
 msgid "Manage Maps"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6168
+#: ../src/menu.c:1415
 msgid "Manage Maps..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:11550
+#: ../src/maps.c:1578
 #, fuzzy
 msgid "Manage Repositories"
 msgstr "Manage Repositories..."
 
-#: ../src/maemo-mapper.c:6170
+#: ../src/menu.c:1417
 msgid "Manage Repositories..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:2291
+#: ../src/display.c:283
 msgid "Manual"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6163
+#: ../src/menu.c:1410
 msgid "Maps"
 msgstr "Kaarten"
 
-#: ../src/maemo-mapper.c:2876
+#: ../src/display.c:868
 msgid "Max speed"
 msgstr ""
 
-#: ../src/maemo-mapper.c:5078
+#: ../src/settings.c:1147
 msgid "Misc."
 msgstr ""
 
-#: ../src/maemo-mapper.c:5114
+#: ../src/settings.c:1204
 #, fuzzy
 msgid "Misc. 2"
 msgstr "Misc."
 
-#: ../src/maemo-mapper.c:3006
+#: ../src/poi.c:163
 msgid "Miscellaneous category for everything else."
 msgstr ""
 
-#: ../src/maemo-mapper.c:12285 ../src/maemo-mapper.c:12449
+#: ../src/maps.c:2294 ../src/menu.c:520
 #, fuzzy
 msgid ""
 "NOTE: You must set a Map URI in the current repository in order to download "
@@ -735,692 +901,776 @@ msgstr ""
 "NOTE: You must set a Map URI in the Repository Manager in order to download "
 "maps."
 
-#: ../src/maemo-mapper.c:11171 ../src/maemo-mapper.c:11409
+#: ../src/maps.c:1197 ../src/maps.c:1437
 msgid "Name"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6262
+#: ../src/menu.c:1495
 #, fuzzy
 msgid "Nearest POI"
 msgstr "Select POI"
 
-#: ../src/maemo-mapper.c:11161
+#: ../src/maps.c:1187
 msgid "New Name"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11399
+#: ../src/maps.c:1427
 msgid "New Repository"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11589
+#: ../src/maps.c:1617
 #, fuzzy
 msgid "New..."
 msgstr "Open..."
 
-#: ../src/maemo-mapper.c:6260
+#: ../src/menu.c:1493
 #, fuzzy
 msgid "Next Waypoint"
 msgstr "Route Markering"
 
-#: ../src/maemo-mapper.c:11362
+#: ../src/maps.c:1390
 msgid "Next-able"
 msgstr ""
 
-#: ../src/maemo-mapper.c:5283
+#: ../src/settings.c:1472
 #, fuzzy
 msgid ""
-"No GPS Receiver MAC provided.\n"
+"No GPS Receiver provided.\n"
 "GPS will be disabled."
 msgstr ""
 "Geen GPS MAC adres opgegeven.\n"
 "GPS uitgeschakeld."
 
-#: ../src/maemo-mapper.c:8530 ../src/maemo-mapper.c:11082
+#: ../src/menu.c:950 ../src/poi.c:391 ../src/poi.c:2772
 msgid "No POIs found."
 msgstr ""
 
-#: ../src/maemo-mapper.c:6243
+#: ../src/poi.c:1401
+msgid "No POIs were found."
+msgstr ""
+
+#: ../src/main.c:309 ../src/menu.c:1556
 msgid "None"
 msgstr "Geen"
 
-#: ../src/maemo-mapper.c:4984
+#: ../src/menu.c:1473
 #, fuzzy
-msgid ""
-"Note: You can enter a device path\n"
-"(e.g. \"/dev/rfcomm0\")."
-msgstr ""
-"Note: For manual rfcomm, enter a device path\n"
-"(e.g. \"/dev/rfcomm0\")."
+msgid "North"
+msgstr "URI Formaat"
 
-#: ../src/maemo-mapper.c:6127 ../src/maemo-mapper.c:6147
+#: ../src/menu.c:1359 ../src/menu.c:1379
 msgid "Open..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:6572
+#: ../src/display.c:1087
 msgid ""
 "OpenStreetMap.org provides public, free-to-use maps.  You can also download "
 "a sample set of repositories from  the internet by using the \"Download...\" "
 "button."
 msgstr ""
 
-#: ../src/maemo-mapper.c:10083
+#: ../src/path.c:1126 ../src/poi.c:2268 ../src/poi.c:2565
 msgid "Origin"
 msgstr "Oorsprong"
 
-#: ../src/maemo-mapper.c:3005
+#: ../src/poi.c:162
 msgid "Other"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12075
+#: ../src/maps.c:2076
 msgid "Overwrite"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4792 ../src/maemo-mapper.c:5177
-#: ../src/maemo-mapper.c:6464
+#: ../src/cmenu.c:647 ../src/menu.c:1395 ../src/menu.c:1534
+#: ../src/settings.c:823 ../src/settings.c:1264
 msgid "POI"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12903
+#: ../src/poi.c:865
 #, fuzzy
 msgid "POI Categories"
 msgstr "POI Categories..."
 
-#: ../src/maemo-mapper.c:6222
-msgid "POI Categories..."
-msgstr ""
+#: ../src/poi.c:1987
+#, fuzzy
+msgid "POI List"
+msgstr "POI"
 
-#: ../src/maemo-mapper.c:5181
+#: ../src/settings.c:1268
 msgid "POI database"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6218
-#, fuzzy
-msgid "POIs"
-msgstr "POI"
+#: ../src/poi.c:1907
+msgid "POIs Exported"
+msgstr ""
 
-#: ../src/maemo-mapper.c:2287
+#: ../src/poi.c:1395
+msgid ""
+"POIs were added to the POI database.  The following screen will allow you to "
+"modify or delete any of the new POIs."
+msgstr ""
+
+#: ../src/display.c:279
 #, fuzzy
 msgid "PPS"
 msgstr "GPS"
 
-#: ../src/maemo-mapper.c:8044
+#: ../src/poi.c:2252
+msgid "Page"
+msgstr ""
+
+#: ../src/menu.c:1460
+msgid "Pan"
+msgstr ""
+
+#: ../src/main.c:245
 msgid "Pan East"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8041
+#: ../src/main.c:242
 msgid "Pan North"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8043
+#: ../src/settings.c:1065
+#, fuzzy
+msgid "Pan Sensitivity"
+msgstr "Gevoeligheid"
+
+#: ../src/main.c:244
 msgid "Pan South"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8042
+#: ../src/main.c:243
 msgid "Pan West"
 msgstr ""
 
-#: ../src/maemo-mapper.c:5067
-msgid "Pitch"
-msgstr "Hoogte"
-
-#: ../src/maemo-mapper.c:2990
+#: ../src/poi.c:147
 msgid "Places to eat or drink."
 msgstr ""
 
-#: ../src/maemo-mapper.c:2992
+#: ../src/poi.c:149
 msgid "Places to shop or acquire services."
 msgstr ""
 
-#: ../src/maemo-mapper.c:2998
+#: ../src/poi.c:155
 msgid "Places to stay temporarily or for the night."
 msgstr ""
 
-#: ../src/maemo-mapper.c:10567
+#: ../src/menu.c:364
 #, fuzzy
 msgid "Please provide a description for the mark."
 msgstr "Geef een bestemmings locatie op a.u.b."
 
-#: ../src/maemo-mapper.c:4519
+#: ../src/settings.c:566
 msgid "Please select a bluetooth device from the list."
 msgstr ""
 
-#: ../src/maemo-mapper.c:13289
+#: ../src/poi.c:1250 ../src/poi.c:1532
 #, fuzzy
-msgid "Please specify a category for the POI."
+msgid "Please specify a category."
 msgstr "Geef een bestemmings locatie op a.u.b."
 
-#: ../src/maemo-mapper.c:13282
+#: ../src/poi.c:2104 ../src/poi.c:2425
 #, fuzzy
-msgid "Please specify a name for the POI."
-msgstr "Geef een bestemmings locatie op a.u.b."
+msgid "Please specify a default category."
+msgstr "Geef een start locatie op a.u.b."
 
-#: ../src/maemo-mapper.c:12719
+#: ../src/poi.c:673
 #, fuzzy
 msgid "Please specify a name for the category."
 msgstr "Geef een start locatie op a.u.b."
 
-#: ../src/maemo-mapper.c:10173
+#: ../src/poi.c:1243
 #, fuzzy
-msgid "Please specify a source URL."
+msgid "Please specify a name."
 msgstr "Geef een bestemmings locatie op a.u.b."
 
-#: ../src/maemo-mapper.c:10217
-msgid "Please specify a start location."
-msgstr "Geef een start locatie op a.u.b."
-
-#: ../src/maemo-mapper.c:10941
+#: ../src/poi.c:2432
 #, fuzzy
-msgid "Please specify an address."
+msgid "Please specify a query."
 msgstr "Geef een bestemmings locatie op a.u.b."
 
-#: ../src/maemo-mapper.c:10224
-msgid "Please specify an end location."
+#: ../src/path.c:1214 ../src/poi.c:2368
+#, fuzzy
+msgid "Please specify a source URL."
 msgstr "Geef een bestemmings locatie op a.u.b."
 
-#: ../src/maemo-mapper.c:13340
-msgid "Problem adding POI"
-msgstr ""
-
-#: ../src/maemo-mapper.c:12756
-msgid "Problem adding category"
-msgstr ""
+#: ../src/path.c:1256
+msgid "Please specify a start location."
+msgstr "Geef een start locatie op a.u.b."
 
-#: ../src/maemo-mapper.c:12567 ../src/maemo-mapper.c:13019
-msgid "Problem deleting POI"
-msgstr ""
+#: ../src/path.c:1263
+msgid "Please specify an end location."
+msgstr "Geef een bestemmings locatie op a.u.b."
 
-#: ../src/maemo-mapper.c:12576
-msgid "Problem deleting category"
-msgstr ""
+#: ../src/poi.c:2419 ../src/poi.c:2696
+#, fuzzy
+msgid "Please specify an origin."
+msgstr "Geef een bestemmings locatie op a.u.b."
 
-#: ../src/maemo-mapper.c:12795
-msgid "Problem updating Category"
+#: ../src/settings.c:1110
+msgid "Points"
 msgstr ""
 
-#: ../src/maemo-mapper.c:13318
-msgid "Problem updating POI"
-msgstr ""
+#: ../src/settings.c:1035
+#, fuzzy
+msgid "Port"
+msgstr "URI Formaat"
 
-#: ../src/maemo-mapper.c:12741
-msgid "Problem updating category"
+#: ../src/maps.c:850
+msgid "Processing Maps"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2946
-msgid "Problem with POI database"
+#: ../src/poi.c:2278 ../src/poi.c:2575
+msgid "Query"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2288
+#: ../src/display.c:280
 msgid "Real Time Kinematic"
 msgstr ""
 
-#: ../src/maemo-mapper.c:3723
+#: ../src/path.c:919
 msgid "Really clear the track?"
 msgstr ""
 
-#: ../src/maemo-mapper.c:3678
+#: ../src/path.c:798
 msgid "Recalculating directions..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:2993
+#: ../src/poi.c:150
 #, fuzzy
 msgid "Recreation"
 msgstr "GPS Locatie"
 
-#: ../src/maemo-mapper.c:11583
+#: ../src/maps.c:1611
 #, fuzzy
 msgid "Rename..."
 msgstr "Open..."
 
-#: ../src/maemo-mapper.c:11440
+#: ../src/maps.c:1468
 msgid "Replace all repositories with the default repository?"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6137
+#: ../src/menu.c:1369 ../src/menu.c:1452
 msgid "Reset"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6281 ../src/maemo-mapper.c:8069
+#: ../src/main.c:278 ../src/menu.c:1585
 msgid "Reset Bluetooth"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4699
+#: ../src/main.c:247
+msgid "Reset Viewing Angle"
+msgstr ""
+
+#: ../src/settings.c:730
 msgid "Reset all colors to their original defaults?"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4580
+#: ../src/settings.c:616
 msgid "Reset all hardware keys to their original defaults?"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4614 ../src/maemo-mapper.c:4735
-#: ../src/maemo-mapper.c:11561
+#: ../src/maps.c:1589 ../src/settings.c:650 ../src/settings.c:766
 #, fuzzy
 msgid "Reset..."
 msgstr "Open..."
 
-#: ../src/maemo-mapper.c:2987
+#: ../src/poi.c:144
 msgid "Residence"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4777 ../src/maemo-mapper.c:6123
-#: ../src/maemo-mapper.c:6204
+#: ../src/poi.c:146
+msgid "Restaurant"
+msgstr ""
+
+#: ../src/main.c:194 ../src/menu.c:1470
+#, fuzzy
+msgid "Right"
+msgstr "Rechts-onder"
+
+#: ../src/menu.c:1444
+#, fuzzy
+msgid "Rotate"
+msgstr "Automatisch-Updaten"
+
+#: ../src/settings.c:1097
+#, fuzzy
+msgid "Rotate Sensit."
+msgstr "Gevoeligheid"
+
+#: ../src/main.c:249
+msgid "Rotate View Clockwise"
+msgstr ""
+
+#: ../src/main.c:251
+msgid "Rotate View Counter-Clockwise"
+msgstr ""
+
+#: ../src/menu.c:1355 ../src/menu.c:1520 ../src/settings.c:808
 msgid "Route"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10311
+#: ../src/path.c:672
 msgid "Route Downloaded"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8368 ../src/maemo-mapper.c:10360
+#: ../src/main.c:485 ../src/menu.c:119
 msgid "Route Opened"
 msgstr "Route Geopend"
 
-#: ../src/maemo-mapper.c:10615
+#: ../src/menu.c:150
 msgid "Route Saved"
 msgstr "Route Opgeslagen"
 
-#: ../src/maemo-mapper.c:10705
+#: ../src/menu.c:1048
 msgid "Routes are now hidden"
 msgstr "Routes zijn nu verborgen"
 
-#: ../src/maemo-mapper.c:10699
+#: ../src/menu.c:1042
 msgid "Routes are now shown"
 msgstr "Routes zijn nu zichtbaar"
 
-#: ../src/maemo-mapper.c:2285
+#: ../src/display.c:277
 msgid "SPS"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2849
+#: ../src/display.c:841
 msgid "Sat in use"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2840
+#: ../src/display.c:832
 msgid "Sat in view"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2781
+#: ../src/display.c:773
 msgid "Satellites details"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2707
+#: ../src/display.c:699
 msgid "Satellites in view"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6131 ../src/maemo-mapper.c:6149
+#: ../src/menu.c:1363 ../src/menu.c:1381
 msgid "Save..."
 msgstr "Opslaan..."
 
-#: ../src/maemo-mapper.c:6199
+#: ../src/menu.c:1510
 msgid "Scale"
 msgstr ""
 
-#: ../src/maemo-mapper.c:4978
+#: ../src/settings.c:1019
 #, fuzzy
 msgid "Scan..."
 msgstr "Opslaan..."
 
-#: ../src/maemo-mapper.c:4495
+#: ../src/settings.c:542
 #, fuzzy
 msgid "Scanning for Bluetooth Devices"
 msgstr "Er wordt naar bluetooth apparaten gezocht"
 
-#: ../src/maemo-mapper.c:2999
+#: ../src/poi.c:156
 msgid "School"
 msgstr ""
 
-#: ../src/maemo-mapper.c:3138
+#: ../src/gps.c:790
 msgid "Searching for GPS receiver"
 msgstr "Er wordt naar GPS ontvanger gezocht"
 
-#: ../src/maemo-mapper.c:4459
+#: ../src/settings.c:506
 #, fuzzy
 msgid "Select Bluetooth Device"
 msgstr "Er wordt naar bluetooth apparaten gezocht"
 
-#: ../src/maemo-mapper.c:8054
+#: ../src/main.c:263
 #, fuzzy
 msgid "Select Next Repository"
 msgstr "Next Repository"
 
-#: ../src/maemo-mapper.c:8560
+#: ../src/poi.c:421
 msgid "Select POI"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8630
+#: ../src/poi.c:1933
+msgid ""
+"Select an operation to perform\n"
+"on the POIs that you checked\n"
+"in the POI list."
+msgstr ""
+
+#: ../src/poi.c:486
 msgid "Select one POI from the list."
 msgstr ""
 
-#: ../src/maemo-mapper.c:4998
-msgid "Sensitivity"
-msgstr "Gevoeligheid"
+#: ../src/poi.c:142
+#, fuzzy
+msgid "Service Station"
+msgstr "GPS Locatie"
+
+#: ../src/poi.c:1502 ../src/poi.c:1939
+#, fuzzy
+msgid "Set Category..."
+msgstr "Category: "
 
-#: ../src/maemo-mapper.c:6431
+#: ../src/cmenu.c:614
 #, fuzzy
 msgid "Set as GPS Location"
 msgstr "Bebruik GPS Locatie"
 
-#: ../src/maemo-mapper.c:4940
+#: ../src/settings.c:980
 #, fuzzy
 msgid "Settings"
 msgstr "Instellingen..."
 
-#: ../src/maemo-mapper.c:6288
+#: ../src/menu.c:1592
 msgid "Settings..."
 msgstr "Instellingen..."
 
-#: ../src/maemo-mapper.c:12058
+#: ../src/maps.c:2059
 msgid "Setup"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2991
+#: ../src/poi.c:148
 msgid "Shopping/Services"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6442
+#: ../src/menu.c:1501
+msgid "Show"
+msgstr ""
+
+#: ../src/cmenu.c:625
 msgid "Show Description"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6157 ../src/maemo-mapper.c:8064
+#: ../src/main.c:273 ../src/menu.c:1389
 #, fuzzy
 msgid "Show Distance from Beginning"
 msgstr "Show Distance to"
 
-#: ../src/maemo-mapper.c:8062
+#: ../src/main.c:271
 #, fuzzy
 msgid "Show Distance from Last Break"
 msgstr "Show Distance to"
 
-#: ../src/maemo-mapper.c:6155
+#: ../src/menu.c:1387
 #, fuzzy
 msgid "Show Distance from Last Mark"
 msgstr "Show Distance to"
 
-#: ../src/maemo-mapper.c:6418 ../src/maemo-mapper.c:6449
-#: ../src/maemo-mapper.c:6473
+#: ../src/cmenu.c:601 ../src/cmenu.c:632 ../src/cmenu.c:656
 msgid "Show Distance to"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6135 ../src/maemo-mapper.c:8058
+#: ../src/main.c:267 ../src/menu.c:1367
 #, fuzzy
 msgid "Show Distance to End of Route"
 msgstr "Show Distance to"
 
-#: ../src/maemo-mapper.c:6133 ../src/maemo-mapper.c:8056
+#: ../src/main.c:265 ../src/menu.c:1365
 #, fuzzy
 msgid "Show Distance to Next Waypoint"
 msgstr "Route Markering"
 
-#: ../src/maemo-mapper.c:6274
+#: ../src/menu.c:1578
 msgid "Show Information"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6415 ../src/maemo-mapper.c:6440
+#: ../src/cmenu.c:598 ../src/cmenu.c:623
 #, fuzzy
 msgid "Show Lat/Lon"
 msgstr "Breedte/Lengtegraad"
 
-#: ../src/maemo-mapper.c:5196
+#: ../src/settings.c:1283
 msgid "Show POI below zoom"
 msgstr ""
 
-#: ../src/maemo-mapper.c:13414
+#: ../src/display.c:2416
 #, fuzzy
 msgid "Show Position"
 msgstr "GPS Locatie"
 
-#: ../src/maemo-mapper.c:2292
+#: ../src/display.c:284
 msgid "Simulation"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10049
+#: ../src/path.c:1086 ../src/poi.c:2220
 msgid "Source URL"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2804 ../src/maemo-mapper.c:5055
+#: ../src/menu.c:1475
+#, fuzzy
+msgid "South"
+msgstr "Route"
+
+#: ../src/display.c:796
 msgid "Speed"
 msgstr "Snelheid"
 
-#: ../src/maemo-mapper.c:5152
+#: ../src/settings.c:1239
 #, fuzzy
 msgid "Speed Limit"
 msgstr "Snelheid"
 
-#: ../src/maemo-mapper.c:2986
+#: ../src/poi.c:143
 msgid "Stations for purchasing fuel for vehicles."
 msgstr ""
 
-#: ../src/maemo-mapper.c:3399
+#: ../src/maps.c:504
+msgid ""
+"The current repository is in a legacy format and will be converted.  You "
+"should delete your old maps if you no longer plan to use them."
+msgstr ""
+
+#: ../src/path.c:551
 msgid "The current route is empty."
 msgstr ""
 
-#: ../src/maemo-mapper.c:3445 ../src/maemo-mapper.c:3460
+#: ../src/path.c:597 ../src/path.c:612
 msgid "The current track is empty."
 msgstr ""
 
-#: ../src/maemo-mapper.c:4660
+#: ../src/settings.c:696
 msgid "The following action is mapped to multiple keys"
 msgstr ""
 
-#: ../src/maemo-mapper.c:9002
+#: ../src/input.c:364
 msgid "There are no other next-able repositories."
 msgstr ""
 
-#: ../src/maemo-mapper.c:13853
+#: ../src/cmenu.c:265 ../src/cmenu.c:287 ../src/cmenu.c:306 ../src/cmenu.c:326
+#: ../src/cmenu.c:345 ../src/cmenu.c:364 ../src/cmenu.c:442 ../src/cmenu.c:461
 msgid "There are no waypoints."
 msgstr ""
 
-#: ../src/maemo-mapper.c:3380 ../src/maemo-mapper.c:11044
+#: ../src/menu.c:912 ../src/path.c:532
 msgid "There is no next waypoint."
 msgstr ""
 
-#: ../src/maemo-mapper.c:8046
+#: ../src/main.c:253
 #, fuzzy
 msgid "Toggle Auto-Center"
 msgstr "Automatisch-Centreren"
 
-#: ../src/maemo-mapper.c:8048
+#: ../src/main.c:255
+#, fuzzy
+msgid "Toggle Auto-Rotate"
+msgstr "Automatisch-Centreren"
+
+#: ../src/main.c:257
 #, fuzzy
 msgid "Toggle Fullscreen"
 msgstr "Volledig Scherm"
 
-#: ../src/maemo-mapper.c:8065
+#: ../src/main.c:274
 #, fuzzy
 msgid "Toggle GPS"
 msgstr "Activeer GPS"
 
-#: ../src/maemo-mapper.c:8066
+#: ../src/main.c:275
 msgid "Toggle GPS Info"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8053
+#: ../src/main.c:262
 #, fuzzy
 msgid "Toggle POIs"
 msgstr "Activeer GPS"
 
-#: ../src/maemo-mapper.c:8052
+#: ../src/main.c:261
 #, fuzzy
 msgid "Toggle Scale"
 msgstr "Activeer GPS"
 
-#: ../src/maemo-mapper.c:8068
+#: ../src/main.c:277
 msgid "Toggle Speed Limit"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8051
+#: ../src/main.c:260
 msgid "Toggle Tracks"
 msgstr ""
 
-#: ../src/maemo-mapper.c:8095 ../src/maemo-mapper.c:12186
+#: ../src/main.c:304 ../src/maps.c:2187
 msgid "Top-Left"
 msgstr "Links-Boven"
 
-#: ../src/maemo-mapper.c:8096
+#: ../src/main.c:305
 #, fuzzy
 msgid "Top-Right"
 msgstr "Rechts-onder"
 
-#: ../src/maemo-mapper.c:4762 ../src/maemo-mapper.c:6143
-#: ../src/maemo-mapper.c:6209
+#: ../src/menu.c:1375 ../src/menu.c:1525 ../src/settings.c:793
 msgid "Track"
 msgstr "Route"
 
-#: ../src/maemo-mapper.c:10434
+#: ../src/menu.c:231
 msgid "Track Opened"
 msgstr "Route Geopend"
 
-#: ../src/maemo-mapper.c:10456
+#: ../src/menu.c:253
 msgid "Track Saved"
 msgstr "Route Opgeslagen"
 
-#: ../src/maemo-mapper.c:10655
+#: ../src/menu.c:985
 msgid "Tracks are now hidden"
 msgstr "Routes zijn nu verborgen"
 
-#: ../src/maemo-mapper.c:10649
+#: ../src/menu.c:979
 msgid "Tracks are now shown"
 msgstr "Routes zijn nu zichtbaar"
 
-#: ../src/maemo-mapper.c:2995
+#: ../src/poi.c:152
 msgid "Transportation"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11278
+#: ../src/maps.c:1304
 msgid "URL Format"
 msgstr "URI Formaat"
 
-#: ../src/maemo-mapper.c:5543
-msgid "Unable to create cache directory for repository"
+#: ../src/maps.c:684
+msgid "Unable to create map database for repository"
 msgstr ""
 
-#: ../src/maemo-mapper.c:5118
+#: ../src/settings.c:1162
+#, fuzzy
+msgid "Unblank Screen"
+msgstr "Volledig Scherm"
+
+#: ../src/settings.c:1191
 msgid "Units"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11003
+#: ../src/util.c:155
 msgid "Unknown error while locating address."
 msgstr ""
 
-#: ../src/maemo-mapper.c:10070
+#: ../src/main.c:193 ../src/menu.c:1464
+msgid "Up"
+msgstr ""
+
+#: ../src/path.c:1103 ../src/poi.c:2233 ../src/poi.c:2531
 msgid "Use End of Route"
 msgstr ""
 
-#: ../src/maemo-mapper.c:10060
+#: ../src/path.c:1097 ../src/poi.c:2227 ../src/poi.c:2525
 msgid "Use GPS Location"
 msgstr "Bebruik GPS Locatie"
 
-#: ../src/maemo-mapper.c:6214
+#: ../src/menu.c:1530
 msgid "Velocity Vector"
 msgstr "Snelheids Factor"
 
-#: ../src/maemo-mapper.c:6181
+#: ../src/menu.c:1428
 msgid "View"
 msgstr ""
 
-#: ../src/maemo-mapper.c:12167
+#: ../src/maps.c:2168
 msgid "View Center"
 msgstr "Bekijk Midden"
 
-#: ../src/maemo-mapper.c:11333
+#: ../src/maps.c:1361
 #, fuzzy
 msgid "View Zoom Steps"
 msgstr "Vergrootings-Stappen"
 
-#: ../src/maemo-mapper.c:6470
+#: ../src/cmenu.c:653
 msgid "View/Edit..."
 msgstr ""
 
-#: ../src/maemo-mapper.c:12554
+#: ../src/poi.c:508
 msgid "WARNING: All POIs in that category will also be deleted!"
 msgstr ""
 
-#: ../src/maemo-mapper.c:6435
+#: ../src/cmenu.c:618
 #, fuzzy
 msgid "Waypoint"
 msgstr "Route Markering"
 
-#: ../src/maemo-mapper.c:6579
+#: ../src/menu.c:1477
+msgid "West"
+msgstr ""
+
+#: ../src/display.c:1094
 msgid ""
 "You will now see a blank screen.  You can download maps using the \"Manage "
 "Maps\" menu item in the \"Maps\" menu.  Or, press OK to enable Auto-Download."
 msgstr ""
 
-#: ../src/maemo-mapper.c:12115
+#: ../src/maps.c:2116 ../src/menu.c:1434
 msgid "Zoom"
 msgstr "Vergroot"
 
-#: ../src/maemo-mapper.c:6185 ../src/maemo-mapper.c:8049
+#: ../src/main.c:258 ../src/menu.c:1438
 #, fuzzy
 msgid "Zoom In"
 msgstr "Vergroot"
 
-#: ../src/maemo-mapper.c:6194
+#: ../src/menu.c:1505
 #, fuzzy
 msgid "Zoom Level"
 msgstr "Vergrootings-Stappen"
 
-#: ../src/maemo-mapper.c:12121
+#: ../src/maps.c:2122
 msgid "Zoom Levels to Download: (0 = most detail)"
 msgstr "Vergrotings-niveaus om te Downloaden: (0 = meeste detail)"
 
-#: ../src/maemo-mapper.c:6187 ../src/maemo-mapper.c:8050
+#: ../src/main.c:259 ../src/menu.c:1440
 #, fuzzy
 msgid "Zoom Out"
 msgstr "Vergroot"
 
-#: ../src/maemo-mapper.c:8815 ../src/maemo-mapper.c:8928
-#: ../src/maemo-mapper.c:12356 ../src/maemo-mapper.c:12374
+#: ../src/input.c:103 ../src/input.c:290 ../src/menu.c:546 ../src/menu.c:564
 #, fuzzy
 msgid "Zoom to Level"
 msgstr "Vergrootings-Stappen"
 
-#: ../src/maemo-mapper.c:11890 ../src/maemo-mapper.c:11897
+#: ../src/maps.c:1880 ../src/maps.c:1887
 #, fuzzy
 msgid "about"
 msgstr "Route"
 
-#: ../src/maemo-mapper.c:2708
+#: ../src/display.c:700
 msgid "in use"
 msgstr ""
 
-#: ../src/maemo-mapper.c:7999
+#: ../src/main.c:189
 msgid "km"
 msgstr ""
 
-#: ../src/maemo-mapper.c:11810 ../src/maemo-mapper.c:11898
+#: ../src/maps.c:1791 ../src/maps.c:1888
 msgid "maps"
 msgstr "kaarten"
 
-#: ../src/maemo-mapper.c:11804 ../src/maemo-mapper.c:11891
+#: ../src/maps.c:1785 ../src/maps.c:1881
 msgid "maps "
 msgstr "kaarten"
 
-#: ../src/maemo-mapper.c:8000
+#: ../src/display.c:1466
+msgid "maps failed to download."
+msgstr ""
+
+#: ../src/main.c:190
 msgid "mi."
 msgstr ""
 
-#: ../src/maemo-mapper.c:8001
+#: ../src/main.c:191
 msgid "n.m."
 msgstr ""
 
-#: ../src/maemo-mapper.c:2862
+#: ../src/display.c:854
 msgid "nofix"
 msgstr ""
 
-#: ../src/maemo-mapper.c:2293 ../src/maemo-mapper.c:2871
+#: ../src/display.c:285 ../src/display.c:863
 #, fuzzy
 msgid "none"
 msgstr "Geen"
 
-#: ../src/maemo-mapper.c:11810 ../src/maemo-mapper.c:11898
+#: ../src/maps.c:1791 ../src/maps.c:1888
 msgid "up to about"
 msgstr ""
 
 #~ msgid "Category List"
 #~ msgstr "Category List"
 
-#~ msgid "Category: "
-#~ msgstr "Category: "
-
 #~ msgid "Copy Description to Clipboard"
 #~ msgstr "Copy Description to Clipboard"
 
@@ -1444,6 +1694,12 @@ msgstr ""
 #~ msgid "Distance to Location"
 #~ msgstr "Bebruik GPS Locatie"
 
+#~ msgid "Downloading maps"
+#~ msgstr "Landkaarten worden gedownload"
+
+#~ msgid "Keep Display On Only in Fullscreen Mode"
+#~ msgstr "Hou het display alleen aan in volledig scherm mode"
+
 #~ msgid "Label: "
 #~ msgstr "Label: "
 
@@ -1458,6 +1714,21 @@ msgstr ""
 #~ msgid "No waypoints found."
 #~ msgstr "No waypoints are visible."
 
+#, fuzzy
+#~ msgid ""
+#~ "Note: You can enter a device path\n"
+#~ "(e.g. \"/dev/rfcomm0\")."
+#~ msgstr ""
+#~ "Note: For manual rfcomm, enter a device path\n"
+#~ "(e.g. \"/dev/rfcomm0\")."
+
+#~ msgid "Pitch"
+#~ msgstr "Hoogte"
+
+#, fuzzy
+#~ msgid "Please specify a name for the POI."
+#~ msgstr "Geef een bestemmings locatie op a.u.b."
+
 #~ msgid "Repositories"
 #~ msgstr "Repositories"
 
index 1df119f840e695eae5ef0432cdae5a8e6c5f42f5..9b42fcbaf7accce528e54c337a07c7ddab4f6408 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-xgettext --keyword=_ -C -s -o template.pot `dirname $0`/../src/maemo-mapper.c
+xgettext --keyword=_ -C -s -o template.pot `sed 's/\\\\$//' POTFILES`
 
 for FILE in `dirname $0`/*.po
 do
index 0e7861b4587a60b9d02dba1ec808162935cd5d6f..7bfada303d02a9e12a0a6a9f004c111a7f6d8a79 100644 (file)
@@ -1,28 +1,43 @@
 #
-# This file is part of maemo-mapper
+# Copyright (C) 2006, 2007 John Costigan.
 #
-# Copyright (C) 2006 John Costigan.
+# This file is part of Maemo Mapper.
 #
-# This program is free software; you can redistribute it and/or modify
+# Maemo Mapper is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
+# the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 #
-# This program is distributed in the hope that it will be useful,
+# Maemo Mapper is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 #
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+# You should have received a copy of the GNU General Public License
+# along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
 #
 
 bin_PROGRAMS = maemo-mapper
 
-maemo_mapper_CFLAGS = $(GTK_CFLAGS) $(OSSO_CFLAGS) $(HILDON_CFLAGS) $(GNOME_VFS_CFLAGS) $(GCONF_CFLAGS) $(LIBXML2_CFLAGS) $(SQLITE_CFLAGS) $(LIBCURL_CFLAGS)
+maemo_mapper_CFLAGS = $(GTK_CFLAGS) $(OSSO_CFLAGS) $(HILDON_CFLAGS) $(GNOME_VFS_CFLAGS) $(GCONF_CFLAGS) $(LIBXML2_CFLAGS) $(SQLITE_CFLAGS) $(CONIC_CFLAGS)
 
-maemo_mapper_LDADD = $(GTK_LIBS) $(OSSO_LIBS) $(HILDON_LIBS) $(GNOME_VFS_LIBS) $(GCONF_LIBS) $(LIBXML2_LIBS) $(SQLITE_LIBS) $(LIBCURL_LIBS)
+maemo_mapper_LDADD = $(GTK_LIBS) $(OSSO_LIBS) $(HILDON_LIBS) $(GNOME_VFS_LIBS) $(GCONF_LIBS) $(LIBXML2_LIBS) $(SQLITE_LIBS) $(CONIC_LIBS) -lgdbm
 
-maemo_mapper_SOURCES = maemo-mapper.c
+maemo_mapper_SOURCES = \
+       cmenu.c \
+       data.c \
+       display.c \
+       gdk-pixbuf-rotate.c \
+       gps.c \
+       gpx.c \
+       input.c \
+       main.c \
+       maps.c \
+       marshal.c \
+       menu.c \
+       path.c \
+       poi.c \
+       settings.c \
+       util.c
 
+# bin_SCRIPTS = maemo-mapper.sh
diff --git a/src/cmenu.c b/src/cmenu.c
new file mode 100644 (file)
index 0000000..264cf6d
--- /dev/null
@@ -0,0 +1,735 @@
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define _GNU_SOURCE
+
+#include <string.h>
+#include <math.h>
+#include <gtk/gtk.h>
+#include <hildon-widgets/hildon-note.h>
+#include <hildon-widgets/hildon-banner.h>
+
+
+#include "types.h"
+#include "data.h"
+#include "defines.h"
+
+#include "cmenu.h"
+#include "display.h"
+#include "gdk-pixbuf-rotate.h"
+#include "menu.h"
+#include "path.h"
+#include "poi.h"
+#include "util.h"
+
+
+static void
+cmenu_show_latlon(gint unitx, gint unity)
+{
+  gfloat lat, lon;
+  gchar buffer[80], tmp1[LL_FMT_LEN], tmp2[LL_FMT_LEN];
+  printf("%s()\n", __PRETTY_FUNCTION__);
+
+  unit2latlon(unitx, unity, lat, lon);
+  lat_format(lat, tmp1);
+  lon_format(lon, tmp2);
+
+  snprintf(buffer, sizeof(buffer),
+            "%s: %s\n"
+          "%s: %s",
+          _("Latitude"), tmp1,
+          _("Longitude"), tmp2);
+
+  MACRO_BANNER_SHOW_INFO(_window, buffer);
+
+  vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+static void
+cmenu_clip_latlon(gint unitx, gint unity)
+{
+    gchar buffer[80];
+    gfloat lat, lon;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    unit2latlon(unitx, unity, lat, lon);
+
+    snprintf(buffer, sizeof(buffer), "%.06f,%.06f", lat, lon);
+
+    gtk_clipboard_set_text(
+            gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), buffer, -1);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+static void
+cmenu_route_to(gint unitx, gint unity)
+{
+    gchar buffer[80];
+    gchar strlat[32];
+    gchar strlon[32];
+    gfloat lat, lon;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    unit2latlon(unitx, unity, lat, lon);
+
+    g_ascii_formatd(strlat, 32, "%.06f", lat);
+    g_ascii_formatd(strlon, 32, "%.06f", lon);
+    snprintf(buffer, sizeof(buffer), "%s, %s", strlat, strlon);
+
+    route_download(buffer);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+static void
+cmenu_distance_to(gint unitx, gint unity)
+{
+    gchar buffer[80];
+    gfloat lat, lon;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    unit2latlon(unitx, unity, lat, lon);
+
+    snprintf(buffer, sizeof(buffer), "%s: %.02f %s", _("Distance"),
+            calculate_distance(_gps.lat, _gps.lon, lat, lon)
+              * UNITS_CONVERT[_units],
+            UNITS_ENUM_TEXT[_units]);
+    MACRO_BANNER_SHOW_INFO(_window, buffer);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+static void
+cmenu_add_route(gint unitx, gint unity)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+    MACRO_PATH_INCREMENT_TAIL(_route);
+    screen2unit(_cmenu_position_x, _cmenu_position_y,
+            _route.tail->unitx, _route.tail->unity);
+    route_find_nearest_point();
+    map_force_redraw();
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+static gboolean
+cmenu_cb_loc_show_latlon(GtkMenuItem *item)
+{
+    gint unitx, unity;
+    gdouble lat, lon;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
+    unit2latlon(unitx, unity, lat, lon);
+
+    latlon_dialog(lat, lon);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+cmenu_cb_loc_route_to(GtkMenuItem *item)
+{
+    gint unitx, unity;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
+    cmenu_route_to(unitx, unity);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+cmenu_cb_loc_download_poi(GtkMenuItem *item)
+{
+    gint unitx, unity;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
+    poi_download_dialog(unitx, unity);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+cmenu_cb_loc_browse_poi(GtkMenuItem *item)
+{
+    gint unitx, unity;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
+    poi_browse_dialog(unitx, unity);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+cmenu_cb_loc_distance_to(GtkMenuItem *item)
+{
+    gint unitx, unity;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
+    cmenu_distance_to(unitx, unity);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+cmenu_cb_loc_add_route(GtkMenuItem *item)
+{
+    gint unitx, unity;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
+    cmenu_add_route(unitx, unity);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+cmenu_cb_loc_add_way(GtkMenuItem *item)
+{
+    gint unitx, unity;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
+    route_add_way_dialog(unitx, unity);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+cmenu_cb_loc_add_poi(GtkMenuItem *item)
+{
+    gint unitx, unity;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
+    poi_view_dialog(NULL, unitx, unity);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+cmenu_cb_loc_set_gps(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    screen2unit(_cmenu_position_x, _cmenu_position_y, _pos.unitx, _pos.unity);
+    unit2latlon(_pos.unitx, _pos.unity, _gps.lat, _gps.lon);
+
+    /* Move mark to new location. */
+    map_refresh_mark(_center_mode > 0);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+cmenu_cb_way_show_latlon(GtkMenuItem *item)
+{
+    gint unitx, unity;
+    WayPoint *way;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
+    if((way = find_nearest_waypoint(unitx, unity)))
+        cmenu_show_latlon(way->point->unitx, way->point->unity);
+    else
+    {
+        MACRO_BANNER_SHOW_INFO(_window, _("There are no waypoints."));
+    }
+
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+cmenu_cb_way_show_desc(GtkMenuItem *item)
+{
+    gint unitx, unity;
+    WayPoint *way;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
+    if((way = find_nearest_waypoint(unitx, unity)))
+    {
+        MACRO_BANNER_SHOW_INFO(_window, way->desc);
+    }
+    else
+    {
+        MACRO_BANNER_SHOW_INFO(_window, _("There are no waypoints."));
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+cmenu_cb_way_clip_latlon(GtkMenuItem *item)
+{
+    gint unitx, unity;
+    WayPoint *way;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
+    if((way = find_nearest_waypoint(unitx, unity)))
+        cmenu_clip_latlon(way->point->unitx, way->point->unity);
+    else
+    {
+        MACRO_BANNER_SHOW_INFO(_window, _("There are no waypoints."));
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+cmenu_cb_way_clip_desc(GtkMenuItem *item)
+{
+    gint unitx, unity;
+    WayPoint *way;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
+    if((way = find_nearest_waypoint(unitx, unity)))
+        gtk_clipboard_set_text(
+                gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), way->desc, -1);
+    else
+    {
+        MACRO_BANNER_SHOW_INFO(_window, _("There are no waypoints."));
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+cmenu_cb_way_route_to(GtkMenuItem *item)
+{
+    gint unitx, unity;
+    WayPoint *way;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
+    if((way = find_nearest_waypoint(unitx, unity)))
+        cmenu_route_to(way->point->unitx, way->point->unity);
+    else
+    {
+        MACRO_BANNER_SHOW_INFO(_window, _("There are no waypoints."));
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+cmenu_cb_way_distance_to(GtkMenuItem *item)
+{
+    gint unitx, unity;
+    WayPoint *way;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
+    if((way = find_nearest_waypoint(unitx, unity)))
+        route_show_distance_to(way->point);
+    else
+    {
+        MACRO_BANNER_SHOW_INFO(_window, _("There are no waypoints."));
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+cmenu_cb_way_delete(GtkMenuItem *item)
+{
+    gint unitx, unity;
+    WayPoint *way;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
+    if((way = find_nearest_waypoint(unitx, unity)))
+    {
+        gchar buffer[BUFFER_SIZE];
+        GtkWidget *confirm;
+
+        snprintf(buffer, sizeof(buffer), "%s:\n%s\n",
+                _("Confirm delete of waypoint"), way->desc);
+        confirm = hildon_note_new_confirmation(GTK_WINDOW(_window), buffer);
+
+        if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm)))
+        {
+            Point *pdel_min, *pdel_max, *pdel_start, *pdel_end;
+            gint num_del;
+
+            /* Delete surrounding route data, too. */
+            if(way == _route.whead)
+                pdel_min = _route.head;
+            else
+                pdel_min = way[-1].point;
+
+            if(way == _route.wtail)
+                pdel_max = _route.tail;
+            else
+                pdel_max = way[1].point;
+
+            /* Find largest continuous segment around the waypoint, EXCLUDING
+             * pdel_min and pdel_max. */
+            for(pdel_start = way->point - 1; pdel_start->unity
+                    && pdel_start > pdel_min; pdel_start--) { }
+            for(pdel_end = way->point + 1; pdel_end->unity
+                    && pdel_end < pdel_max; pdel_end++) { }
+
+            /* If pdel_end is set to _route.tail, and if _route.tail is a
+             * non-zero point, then delete _route.tail. */
+            if(pdel_end == _route.tail && pdel_end->unity)
+                pdel_end++; /* delete _route.tail too */
+            /* else, if *both* endpoints are zero points, delete one. */
+            else if(!pdel_start->unity && !pdel_end->unity)
+                pdel_start--;
+
+            /* Delete BETWEEN pdel_start and pdel_end, exclusive. */
+            num_del = pdel_end - pdel_start - 1;
+
+            memmove(pdel_start + 1, pdel_end,
+                    (_route.tail - pdel_end + 1) * sizeof(Point));
+            _route.tail -= num_del;
+
+            /* Remove waypoint and move/adjust subsequent waypoints. */
+            g_free(way->desc);
+            while(way++ != _route.wtail)
+            {
+                way[-1] = *way;
+                way[-1].point -= num_del;
+            }
+            _route.wtail--;
+
+            route_find_nearest_point();
+            map_force_redraw();
+        }
+        gtk_widget_destroy(confirm);
+    }
+    else
+    {
+        MACRO_BANNER_SHOW_INFO(_window, _("There are no waypoints."));
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+cmenu_cb_way_add_poi(GtkMenuItem *item)
+{
+    gint unitx, unity;
+    WayPoint *way;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
+    if((way = find_nearest_waypoint(unitx, unity)))
+        poi_view_dialog(NULL, way->point->unitx, way->point->unity);
+    else
+    {
+        MACRO_BANNER_SHOW_INFO(_window, _("There are no waypoints."));
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+cmenu_cb_poi_route_to(GtkMenuItem *item)
+{
+    gint unitx, unity;
+    PoiInfo poi;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
+    if(select_poi(unitx, unity, &poi, FALSE)) /* FALSE = not quick */
+    {
+        gint unitx, unity;
+        latlon2unit(poi.lat, poi.lon, unitx, unity);
+        cmenu_route_to(unitx, unity);
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+cmenu_cb_poi_distance_to(GtkMenuItem *item)
+{
+    gint unitx, unity;
+    PoiInfo poi;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
+    if(select_poi(unitx, unity, &poi, FALSE)) /* FALSE = not quick */
+    {
+        gint unitx, unity;
+        latlon2unit(poi.lat, poi.lon, unitx, unity);
+        cmenu_distance_to(unitx, unity);
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+cmenu_cb_poi_add_route(GtkMenuItem *item)
+{
+    gint unitx, unity;
+    PoiInfo poi;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
+    if(select_poi(unitx, unity, &poi, FALSE)) /* FALSE = not quick */
+    {
+        gint unitx, unity;
+        latlon2unit(poi.lat, poi.lon, unitx, unity);
+        cmenu_add_route(unitx, unity);
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+cmenu_cb_poi_add_way(GtkMenuItem *item)
+{
+    gint unitx, unity;
+    PoiInfo poi;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
+    if(select_poi(unitx, unity, &poi, FALSE)) /* FALSE = not quick */
+    {
+        gint unitx, unity;
+        latlon2unit(poi.lat, poi.lon, unitx, unity);
+        route_add_way_dialog(unitx, unity);
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+cmenu_cb_poi_edit_poi(GtkMenuItem *item)
+{
+    PoiInfo poi;
+    gint unitx, unity;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    memset(&poi, 0, sizeof(poi));
+    screen2unit(_cmenu_position_x, _cmenu_position_y, unitx, unity);
+    select_poi(unitx, unity, &poi, FALSE); /* FALSE = not quick */
+    poi_view_dialog(&poi, unitx, unity);
+    if(poi.label)
+        g_free(poi.label);
+    if(poi.desc)
+        g_free(poi.desc);
+    if(poi.clabel)
+        g_free(poi.clabel);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+cmenu_cb_hide(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(_mouse_is_down)
+        g_mutex_unlock(_mouse_mutex);
+    _mouse_is_down = _mouse_is_dragging = FALSE;
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+void cmenu_init()
+{
+    /* Create needed handles. */
+    GtkMenu *menu;
+    GtkWidget *submenu;
+    GtkWidget *menu_item;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    /* Setup the context menu. */
+    menu = GTK_MENU(gtk_menu_new());
+
+    /* Setup the map context menu. */
+    gtk_menu_append(menu, menu_item
+            = gtk_menu_item_new_with_label(_("Location")));
+    gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
+            submenu = gtk_menu_new());
+
+    /* Setup the map context menu. */
+    gtk_menu_append(submenu, _cmenu_loc_show_latlon_item
+            = gtk_menu_item_new_with_label(_("Show Lat/Lon")));
+    gtk_menu_append(submenu, gtk_separator_menu_item_new());
+    gtk_menu_append(submenu, _cmenu_loc_distance_to_item
+            = gtk_menu_item_new_with_label(_("Show Distance to")));
+    gtk_menu_append(submenu, _cmenu_loc_route_to_item
+            = gtk_menu_item_new_with_label(_("Download Route to...")));
+    gtk_menu_append(submenu, _cmenu_loc_download_poi_item
+                = gtk_menu_item_new_with_label(_("Download POI...")));
+    gtk_menu_append(submenu, _cmenu_loc_browse_poi_item
+                = gtk_menu_item_new_with_label(_("Browse POI...")));
+    gtk_menu_append(submenu, gtk_separator_menu_item_new());
+    gtk_menu_append(submenu, _cmenu_loc_add_route_item
+                = gtk_menu_item_new_with_label(_("Add Route Point")));
+    gtk_menu_append(submenu, _cmenu_loc_add_way_item
+                = gtk_menu_item_new_with_label(_("Add Waypoint...")));
+    gtk_menu_append(submenu, _cmenu_loc_add_poi_item
+                = gtk_menu_item_new_with_label(_("Add POI...")));
+    gtk_menu_append(submenu, gtk_separator_menu_item_new());
+    gtk_menu_append(submenu, _cmenu_loc_set_gps_item
+                = gtk_menu_item_new_with_label(_("Set as GPS Location")));
+
+    /* Setup the waypoint context menu. */
+    gtk_menu_append(menu, menu_item
+            = gtk_menu_item_new_with_label(_("Waypoint")));
+    gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
+            submenu = gtk_menu_new());
+
+    gtk_menu_append(submenu, _cmenu_way_show_latlon_item
+            = gtk_menu_item_new_with_label(_("Show Lat/Lon")));
+    gtk_menu_append(submenu, _cmenu_way_show_desc_item
+            = gtk_menu_item_new_with_label(_("Show Description")));
+    gtk_menu_append(submenu, _cmenu_way_clip_latlon_item
+            = gtk_menu_item_new_with_label(_("Copy Lat/Lon")));
+    gtk_menu_append(submenu, _cmenu_way_clip_desc_item
+            = gtk_menu_item_new_with_label(_("Copy Description")));
+    gtk_menu_append(submenu, gtk_separator_menu_item_new());
+    gtk_menu_append(submenu, _cmenu_way_distance_to_item
+            = gtk_menu_item_new_with_label(_("Show Distance to")));
+    gtk_menu_append(submenu, _cmenu_way_route_to_item
+            = gtk_menu_item_new_with_label(_("Download Route to...")));
+    gtk_menu_append(submenu, _cmenu_way_delete_item
+            = gtk_menu_item_new_with_label(_("Delete...")));
+    gtk_menu_append(submenu, gtk_separator_menu_item_new());
+    gtk_menu_append(submenu, _cmenu_way_add_poi_item
+                = gtk_menu_item_new_with_label(_("Add POI...")));
+    gtk_menu_append(submenu, gtk_separator_menu_item_new());
+    gtk_menu_append(submenu, _cmenu_way_goto_nextway_item
+                = gtk_menu_item_new_with_label(_("Go to Next")));
+
+    /* Setup the POI context menu. */
+    gtk_menu_append(menu, _cmenu_poi_submenu
+            = gtk_menu_item_new_with_label(_("POI")));
+    gtk_menu_item_set_submenu(GTK_MENU_ITEM(_cmenu_poi_submenu),
+            submenu = gtk_menu_new());
+
+    gtk_menu_append(submenu, _cmenu_poi_edit_poi_item
+                = gtk_menu_item_new_with_label(_("View/Edit...")));
+    gtk_menu_append(submenu, gtk_separator_menu_item_new());
+    gtk_menu_append(submenu, _cmenu_poi_distance_to_item
+            = gtk_menu_item_new_with_label(_("Show Distance to")));
+    gtk_menu_append(submenu, _cmenu_poi_route_to_item
+            = gtk_menu_item_new_with_label(_("Download Route to...")));
+    gtk_menu_append(submenu, gtk_separator_menu_item_new());
+    gtk_menu_append(submenu, _cmenu_poi_add_route_item
+                = gtk_menu_item_new_with_label(_("Add Route Point")));
+    gtk_menu_append(submenu, _cmenu_poi_add_way_item
+                = gtk_menu_item_new_with_label(_("Add Waypoint...")));
+    gtk_menu_append(submenu, gtk_separator_menu_item_new());
+    gtk_menu_append(submenu, _cmenu_poi_goto_nearpoi_item
+                = gtk_menu_item_new_with_label(_("Go to Nearest")));
+
+    /* Connect signals for context menu. */
+    g_signal_connect(G_OBJECT(_cmenu_loc_show_latlon_item), "activate",
+                      G_CALLBACK(cmenu_cb_loc_show_latlon), NULL);
+    g_signal_connect(G_OBJECT(_cmenu_loc_route_to_item), "activate",
+                      G_CALLBACK(cmenu_cb_loc_route_to), NULL);
+    g_signal_connect(G_OBJECT(_cmenu_loc_download_poi_item), "activate",
+                      G_CALLBACK(cmenu_cb_loc_download_poi), NULL);
+    g_signal_connect(G_OBJECT(_cmenu_loc_browse_poi_item), "activate",
+                      G_CALLBACK(cmenu_cb_loc_browse_poi), NULL);
+    g_signal_connect(G_OBJECT(_cmenu_loc_distance_to_item), "activate",
+                      G_CALLBACK(cmenu_cb_loc_distance_to), NULL);
+    g_signal_connect(G_OBJECT(_cmenu_loc_add_route_item), "activate",
+                        G_CALLBACK(cmenu_cb_loc_add_route), NULL);
+    g_signal_connect(G_OBJECT(_cmenu_loc_add_way_item), "activate",
+                        G_CALLBACK(cmenu_cb_loc_add_way), NULL);
+    g_signal_connect(G_OBJECT(_cmenu_loc_add_poi_item), "activate",
+                        G_CALLBACK(cmenu_cb_loc_add_poi), NULL);
+    g_signal_connect(G_OBJECT(_cmenu_loc_set_gps_item), "activate",
+                        G_CALLBACK(cmenu_cb_loc_set_gps), NULL);
+
+    g_signal_connect(G_OBJECT(_cmenu_way_show_latlon_item), "activate",
+                      G_CALLBACK(cmenu_cb_way_show_latlon), NULL);
+    g_signal_connect(G_OBJECT(_cmenu_way_show_desc_item), "activate",
+                      G_CALLBACK(cmenu_cb_way_show_desc), NULL);
+    g_signal_connect(G_OBJECT(_cmenu_way_clip_latlon_item), "activate",
+                      G_CALLBACK(cmenu_cb_way_clip_latlon), NULL);
+    g_signal_connect(G_OBJECT(_cmenu_way_clip_desc_item), "activate",
+                      G_CALLBACK(cmenu_cb_way_clip_desc), NULL);
+    g_signal_connect(G_OBJECT(_cmenu_way_route_to_item), "activate",
+                      G_CALLBACK(cmenu_cb_way_route_to), NULL);
+    g_signal_connect(G_OBJECT(_cmenu_way_distance_to_item), "activate",
+                      G_CALLBACK(cmenu_cb_way_distance_to), NULL);
+    g_signal_connect(G_OBJECT(_cmenu_way_delete_item), "activate",
+                      G_CALLBACK(cmenu_cb_way_delete), NULL);
+    g_signal_connect(G_OBJECT(_cmenu_way_add_poi_item), "activate",
+                        G_CALLBACK(cmenu_cb_way_add_poi), NULL);
+    g_signal_connect(G_OBJECT(_cmenu_way_goto_nextway_item), "activate",
+                        G_CALLBACK(menu_cb_view_goto_nextway), NULL);
+
+    g_signal_connect(G_OBJECT(_cmenu_poi_edit_poi_item), "activate",
+                        G_CALLBACK(cmenu_cb_poi_edit_poi), NULL);
+    g_signal_connect(G_OBJECT(_cmenu_poi_route_to_item), "activate",
+                      G_CALLBACK(cmenu_cb_poi_route_to), NULL);
+    g_signal_connect(G_OBJECT(_cmenu_poi_distance_to_item), "activate",
+                      G_CALLBACK(cmenu_cb_poi_distance_to), NULL);
+    g_signal_connect(G_OBJECT(_cmenu_poi_add_route_item), "activate",
+                        G_CALLBACK(cmenu_cb_poi_add_route), NULL);
+    g_signal_connect(G_OBJECT(_cmenu_poi_add_way_item), "activate",
+                        G_CALLBACK(cmenu_cb_poi_add_way), NULL);
+    g_signal_connect(G_OBJECT(_cmenu_poi_goto_nearpoi_item), "activate",
+                        G_CALLBACK(menu_cb_view_goto_nearpoi), NULL);
+
+    gtk_widget_show_all(GTK_WIDGET(menu));
+
+    gtk_widget_tap_and_hold_setup(_map_widget, GTK_WIDGET(menu), NULL, 0);
+
+    /* Add a "hide" signal event handler to handle dismissing the context
+     * menu. */
+    g_signal_connect(GTK_WIDGET(menu), "hide",
+            G_CALLBACK(cmenu_cb_hide), NULL);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
diff --git a/src/cmenu.h b/src/cmenu.h
new file mode 100644 (file)
index 0000000..f82da9e
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAEMO_MAPPER_CMENU
+#define MAEMO_MAPPER_CMENU
+
+void cmenu_init();
+
+#endif /* ifndef MAEMO_MAPPER_CMENU */
diff --git a/src/data.c b/src/data.c
new file mode 100644 (file)
index 0000000..629ffce
--- /dev/null
@@ -0,0 +1,342 @@
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define _GNU_SOURCE
+
+#include "types.h"
+#include "data.h"
+#include "defines.h"
+
+/* Constants regarding enums and defaults. */
+gchar *UNITS_ENUM_TEXT[UNITS_ENUM_COUNT];
+
+/* UNITS_CONVERT, when multiplied, converts from NM. */
+gfloat UNITS_CONVERT[] =
+{
+    1.85200,
+    1.15077945,
+    1.f,
+};
+
+gchar *UNBLANK_ENUM_TEXT[UNBLANK_ENUM_COUNT];
+gchar *INFO_FONT_ENUM_TEXT[INFO_FONT_ENUM_COUNT];
+gchar *ROTATE_DIR_ENUM_TEXT[ROTATE_DIR_ENUM_COUNT];
+gint ROTATE_DIR_ENUM_DEGREES[ROTATE_DIR_ENUM_COUNT] = { 0, 90, 180, 270 };
+gchar *CUSTOM_ACTION_ENUM_TEXT[CUSTOM_ACTION_ENUM_COUNT];
+gchar *CUSTOM_KEY_GCONF[CUSTOM_KEY_ENUM_COUNT];
+gchar *CUSTOM_KEY_ICON[CUSTOM_KEY_ENUM_COUNT];
+CustomAction CUSTOM_KEY_DEFAULT[CUSTOM_KEY_ENUM_COUNT];
+gchar *COLORABLE_GCONF[COLORABLE_ENUM_COUNT];
+GdkColor COLORABLE_DEFAULT[COLORABLE_ENUM_COUNT] =
+{
+    {0, 0x0000, 0x0000, 0xc000}, /* COLORABLE_MARK */
+    {0, 0x6000, 0x6000, 0xf800}, /* COLORABLE_MARK_VELOCITY */
+    {0, 0x8000, 0x8000, 0x8000}, /* COLORABLE_MARK_OLD */
+    {0, 0xe000, 0x0000, 0x0000}, /* COLORABLE_TRACK */
+    {0, 0xa000, 0x0000, 0x0000}, /* COLORABLE_TRACK_MARK */
+    {0, 0x7000, 0x0000, 0x0000}, /* COLORABLE_TRACK_BREAK */
+    {0, 0x0000, 0xa000, 0x0000}, /* COLORABLE_ROUTE */
+    {0, 0x0000, 0x8000, 0x0000}, /* COLORABLE_ROUTE_WAY */
+    {0, 0x0000, 0x6000, 0x0000}, /* COLORABLE_ROUTE_BREAK */
+    {0, 0xa000, 0x0000, 0xa000}  /* COLORABLE_POI */
+};
+gchar *DEG_FORMAT_ENUM_TEXT[DEG_FORMAT_ENUM_COUNT];
+gchar *SPEED_LOCATION_ENUM_TEXT[SPEED_LOCATION_ENUM_COUNT];
+gchar *GPS_RCVR_ENUM_TEXT[GPS_RCVR_ENUM_COUNT];
+
+/** The main GtkContainer of the application. */
+GtkWidget *_window = NULL;
+
+/** The main OSSO context of the application. */
+osso_context_t *_osso = NULL;
+
+/** The widget that provides the visual display of the map. */
+GtkWidget *_map_widget = NULL;
+
+/** The backing pixmap of _map_widget. */
+GdkPixmap *_map_pixmap = NULL;
+
+/** The backing pixmap of _map_widget. */
+GdkPixbuf *_map_pixbuf = NULL;
+
+gint _map_offset_devx;
+gint _map_offset_devy;
+
+gint _map_rotate_angle = 0;
+gfloat _map_rotate_matrix[4] = { 1.f, 0.f, 0.f, 1.f };
+gfloat _map_reverse_matrix[4] = { 1.f, 0.f, 0.f, 1.f };
+
+GtkWidget *_gps_widget = NULL;
+GtkWidget *_text_lat = NULL;
+GtkWidget *_text_lon = NULL;
+GtkWidget *_text_speed = NULL;
+GtkWidget *_text_alt = NULL;
+GtkWidget *_sat_panel = NULL;
+GtkWidget *_text_time = NULL;
+GtkWidget *_heading_panel = NULL;
+
+/** GPS data. */
+Point _pos = { 0, 0, 0, INT_MIN};
+const Point _point_null = { 0, 0, 0, 0};
+
+GpsData _gps;
+GpsSatelliteData _gps_sat[12];
+gboolean _satdetails_on = FALSE;
+
+
+/** VARIABLES FOR MAINTAINING STATE OF THE CURRENT VIEW. */
+
+/** The "zoom" level defines the resolution of a pixel, from 0 to MAX_ZOOM.
+ * Each pixel in the current view is exactly (1 << _zoom) "units" wide. */
+gint _zoom = 3; /* zoom level, from 0 to MAX_ZOOM. */
+Point _center = {-1, -1}; /* current center location, X. */
+
+gint _next_zoom = 3;
+Point _next_center = {-1, -1};
+gint _next_map_rotate_angle = 0;
+GdkPixbuf *_redraw_wait_icon = NULL;
+GdkRectangle _redraw_wait_bounds = { 0, 0, 0, 0};
+
+
+/** CACHED SCREEN INFORMATION THAT IS DEPENDENT ON THE CURRENT VIEW. */
+gint _screen_width_pixels = 0;
+gint _screen_height_pixels = 0;
+gint _screen_halfwidth_pixels = 0;
+gint _screen_halfheight_pixels = 0;
+
+
+/** The current track and route. */
+Path _track;
+Path _route;
+gint _track_index_last_saved = 0;
+
+/** THE GdkGC OBJECTS USED FOR DRAWING. */
+GdkGC *_gc[COLORABLE_ENUM_COUNT];
+GdkColor _color[COLORABLE_ENUM_COUNT];
+
+/** BANNERS. */
+GtkWidget *_connect_banner = NULL;
+GtkWidget *_fix_banner = NULL;
+GtkWidget *_waypoint_banner = NULL;
+GtkWidget *_download_banner = NULL;
+
+/** DOWNLOAD PROGRESS. */
+GMutex *_mapdb_mutex = NULL;
+GMutex *_mouse_mutex = NULL;
+volatile gint _num_downloads = 0;
+gint _curr_download = 0;
+GHashTable *_mut_exists_table = NULL;
+GTree *_mut_priority_tree = NULL;
+GMutex *_mut_priority_mutex = NULL;
+/* NOMORE gint _dl_errors = 0; */
+GThreadPool *_mut_thread_pool = NULL;
+GThreadPool *_mrt_thread_pool = NULL;
+
+/** CONFIGURATION INFORMATION. */
+GpsRcvrInfo _gri = { 0, 0, 0, 0, 0, 0 };
+ConnState _gps_state;
+gchar *_route_dir_uri = NULL;
+gchar *_track_file_uri = NULL;
+CenterMode _center_mode = CENTER_LEAD;
+gboolean _center_rotate = TRUE;
+gboolean _fullscreen = FALSE;
+gboolean _enable_gps = FALSE;
+gboolean _gps_info = FALSE;
+gchar *_route_dl_url = NULL;
+gint _route_dl_radius = 4;
+gchar *_poi_dl_url = NULL;
+gint _show_paths = 0;
+gboolean _show_zoomlevel = TRUE;
+gboolean _show_scale = TRUE;
+gboolean _show_comprose = TRUE;
+gboolean _show_velvec = TRUE;
+gboolean _show_poi = TRUE;
+gboolean _auto_download = FALSE;
+gint _auto_download_precache = 2;
+gint _lead_ratio = 5;
+gboolean _lead_is_fixed = FALSE;
+gint _center_ratio = 5;
+gint _draw_width = 5;
+gint _rotate_sens = 5;
+RotateDir _rotate_dir = ROTATE_DIR_UP;
+gint _announce_notice_ratio = 8;
+gboolean _enable_voice = TRUE;
+GSList *_loc_list;
+GtkListStore *_loc_model;
+UnitType _units = UNITS_KM;
+CustomAction _action[CUSTOM_KEY_ENUM_COUNT];
+gint _degformat = DDPDDDDD;
+gboolean _speed_limit_on = FALSE;
+gint _speed_limit = 100;
+gboolean _speed_excess = FALSE;
+SpeedLocation _speed_location = SPEED_LOCATION_TOP_RIGHT;
+UnblankOption _unblank_option = UNBLANK_FULLSCREEN;
+InfoFontSize _info_font_size = INFO_FONT_MEDIUM;
+
+GList *_repo_list = NULL;
+RepoData *_curr_repo = NULL;
+
+/** POI */
+gchar *_poi_db_filename = NULL;
+gchar *_poi_db_dirname = NULL;
+gint _poi_zoom = 6;
+gboolean _poi_enabled = FALSE;
+
+/** The singleton auto-route-download data. */
+AutoRouteDownloadData _autoroute_data;
+
+
+/*********************
+ * BELOW: MENU ITEMS *
+ *********************/
+
+/* Menu items for the "Route" submenu. */
+GtkWidget *_menu_route_open_item = NULL;
+GtkWidget *_menu_route_download_item = NULL;
+GtkWidget *_menu_route_save_item = NULL;
+GtkWidget *_menu_route_distnext_item = NULL;
+GtkWidget *_menu_route_distlast_item = NULL;
+GtkWidget *_menu_route_reset_item = NULL;
+GtkWidget *_menu_route_clear_item = NULL;
+
+/* Menu items for the "Track" submenu. */
+GtkWidget *_menu_track_open_item = NULL;
+GtkWidget *_menu_track_save_item = NULL;
+GtkWidget *_menu_track_insert_break_item = NULL;
+GtkWidget *_menu_track_insert_mark_item = NULL;
+GtkWidget *_menu_track_distlast_item = NULL;
+GtkWidget *_menu_track_distfirst_item = NULL;
+GtkWidget *_menu_track_clear_item = NULL;
+
+/* Menu items for the "POI" submenu. */
+GtkWidget *_menu_poi_item = NULL;
+GtkWidget *_menu_poi_import_item = NULL;
+GtkWidget *_menu_poi_download_item = NULL;
+GtkWidget *_menu_poi_browse_item = NULL;
+GtkWidget *_menu_poi_categories_item = NULL;
+
+/* Menu items for the "Maps" submenu. */
+GtkWidget *_menu_maps_submenu = NULL;
+GtkWidget *_menu_maps_mapman_item = NULL;
+GtkWidget *_menu_maps_repoman_item = NULL;
+GtkWidget *_menu_maps_auto_download_item = NULL;
+
+/* Menu items for the "View" submenu. */
+GtkWidget *_menu_view_zoom_in_item = NULL;
+GtkWidget *_menu_view_zoom_out_item = NULL;
+
+GtkWidget *_menu_view_rotate_clock_item = NULL;
+GtkWidget *_menu_view_rotate_counter_item = NULL;
+GtkWidget *_menu_view_rotate_reset_item = NULL;
+GtkWidget *_menu_view_rotate_auto_item = NULL;
+
+GtkWidget *_menu_view_pan_up_item = NULL;
+GtkWidget *_menu_view_pan_down_item = NULL;
+GtkWidget *_menu_view_pan_left_item = NULL;
+GtkWidget *_menu_view_pan_right_item = NULL;
+GtkWidget *_menu_view_pan_north_item = NULL;
+GtkWidget *_menu_view_pan_south_item = NULL;
+GtkWidget *_menu_view_pan_west_item = NULL;
+GtkWidget *_menu_view_pan_east_item = NULL;
+
+GtkWidget *_menu_view_fullscreen_item = NULL;
+
+GtkWidget *_menu_view_show_zoomlevel_item = NULL;
+GtkWidget *_menu_view_show_scale_item = NULL;
+GtkWidget *_menu_view_show_comprose_item = NULL;
+GtkWidget *_menu_view_show_routes_item = NULL;
+GtkWidget *_menu_view_show_tracks_item = NULL;
+GtkWidget *_menu_view_show_velvec_item = NULL;
+GtkWidget *_menu_view_show_poi_item = NULL;
+
+GtkWidget *_menu_view_ac_latlon_item = NULL;
+GtkWidget *_menu_view_ac_lead_item = NULL;
+GtkWidget *_menu_view_ac_none_item = NULL;
+
+GtkWidget *_menu_view_goto_latlon_item = NULL;
+GtkWidget *_menu_view_goto_address_item = NULL;
+GtkWidget *_menu_view_goto_gps_item = NULL;
+GtkWidget *_menu_view_goto_nextway_item = NULL;
+GtkWidget *_menu_view_goto_nearpoi_item = NULL;
+
+/* Menu items for the "GPS" submenu. */
+GtkWidget *_menu_enable_gps_item = NULL;
+GtkWidget *_menu_gps_show_info_item = NULL;
+GtkWidget *_menu_gps_details_item = NULL;
+GtkWidget *_menu_gps_reset_item = NULL;
+
+/* Menu items for the other menu items. */
+GtkWidget *_menu_settings_item = NULL;
+GtkWidget *_menu_help_item = NULL;
+GtkWidget *_menu_about_item = NULL;
+GtkWidget *_menu_close_item = NULL;
+
+/*********************
+ * ABOVE: MENU ITEMS *
+ *********************/
+
+
+/*****************************
+ * BELOW: CONTEXT MENU ITEMS *
+ *****************************/
+
+gboolean _mouse_is_dragging = FALSE;
+gboolean _mouse_is_down = FALSE;
+gint _cmenu_position_x = 0;
+gint _cmenu_position_y = 0;
+
+/* Menu items for the "Location" context menu. */
+GtkWidget *_cmenu_loc_show_latlon_item = NULL;
+GtkWidget *_cmenu_loc_route_to_item = NULL;
+GtkWidget *_cmenu_loc_distance_to_item = NULL;
+GtkWidget *_cmenu_loc_download_poi_item = NULL;
+GtkWidget *_cmenu_loc_browse_poi_item = NULL;
+GtkWidget *_cmenu_loc_add_route_item = NULL;
+GtkWidget *_cmenu_loc_add_way_item = NULL;
+GtkWidget *_cmenu_loc_add_poi_item = NULL;
+GtkWidget *_cmenu_loc_set_gps_item = NULL;
+
+/* Menu items for the "Waypoint" context menu. */
+GtkWidget *_cmenu_way_show_latlon_item = NULL;
+GtkWidget *_cmenu_way_show_desc_item = NULL;
+GtkWidget *_cmenu_way_clip_latlon_item = NULL;
+GtkWidget *_cmenu_way_clip_desc_item = NULL;
+GtkWidget *_cmenu_way_route_to_item = NULL;
+GtkWidget *_cmenu_way_distance_to_item = NULL;
+GtkWidget *_cmenu_way_delete_item = NULL;
+GtkWidget *_cmenu_way_add_poi_item = NULL;
+GtkWidget *_cmenu_way_goto_nextway_item = NULL;
+
+/* Menu items for the "POI" context menu. */
+GtkWidget *_cmenu_poi_submenu = NULL;
+GtkWidget *_cmenu_poi_edit_poi_item = NULL;
+GtkWidget *_cmenu_poi_route_to_item = NULL;
+GtkWidget *_cmenu_poi_distance_to_item = NULL;
+GtkWidget *_cmenu_poi_add_route_item = NULL;
+GtkWidget *_cmenu_poi_add_way_item = NULL;
+GtkWidget *_cmenu_poi_goto_nearpoi_item = NULL;
+
+/*****************************
+ * ABOVE: CONTEXT MENU ITEMS *
+ *****************************/
+
diff --git a/src/data.h b/src/data.h
new file mode 100644 (file)
index 0000000..21f467f
--- /dev/null
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAEMO_MAPPER_DATA_H
+#define MAEMO_MAPPER_DATA_H
+
+#include <libosso.h>
+
+/* Constants regarding enums and defaults. */
+extern gchar *UNITS_ENUM_TEXT[UNITS_ENUM_COUNT];
+extern gfloat UNITS_CONVERT[UNITS_ENUM_COUNT];
+extern gchar *UNBLANK_ENUM_TEXT[UNBLANK_ENUM_COUNT];
+extern gchar *INFO_FONT_ENUM_TEXT[INFO_FONT_ENUM_COUNT];
+extern gchar *ROTATE_DIR_ENUM_TEXT[ROTATE_DIR_ENUM_COUNT];
+extern gint ROTATE_DIR_ENUM_DEGREES[ROTATE_DIR_ENUM_COUNT];
+extern gchar *CUSTOM_ACTION_ENUM_TEXT[CUSTOM_ACTION_ENUM_COUNT];
+extern gchar *CUSTOM_KEY_GCONF[CUSTOM_KEY_ENUM_COUNT];
+extern gchar *CUSTOM_KEY_ICON[CUSTOM_KEY_ENUM_COUNT];
+extern CustomAction CUSTOM_KEY_DEFAULT[CUSTOM_KEY_ENUM_COUNT];
+extern gchar *COLORABLE_GCONF[COLORABLE_ENUM_COUNT];
+extern GdkColor COLORABLE_DEFAULT[COLORABLE_ENUM_COUNT];
+extern gchar *DEG_FORMAT_ENUM_TEXT[DEG_FORMAT_ENUM_COUNT];
+extern gchar *SPEED_LOCATION_ENUM_TEXT[SPEED_LOCATION_ENUM_COUNT];
+extern gchar *GPS_RCVR_ENUM_TEXT[GPS_RCVR_ENUM_COUNT];
+
+/** The main GtkContainer of the application. */
+extern GtkWidget *_window;
+
+/** The main OSSO context of the application. */
+extern osso_context_t *_osso;
+
+/** The widget that provides the visual display of the map. */
+extern GtkWidget *_map_widget;
+
+/** The backing pixmap of _map_widget. */
+extern GdkPixmap *_map_pixmap;
+
+/** The backing pixmap of _map_widget. */
+extern GdkPixbuf *_map_pixbuf;
+
+extern gint _map_offset_devx;
+extern gint _map_offset_devy;
+
+extern gint _map_rotate_angle;
+extern gfloat _map_rotate_matrix[4];
+extern gfloat _map_reverse_matrix[4];
+
+extern GtkWidget *_gps_widget;
+extern GtkWidget *_text_lat;
+extern GtkWidget *_text_lon;
+extern GtkWidget *_text_speed;
+extern GtkWidget *_text_alt;
+extern GtkWidget *_sat_panel;
+extern GtkWidget *_text_time;
+extern GtkWidget *_heading_panel;
+
+/** GPS data. */
+extern Point _pos;
+extern const Point _point_null;
+
+extern GpsData _gps;
+extern GpsSatelliteData _gps_sat[12];
+extern gboolean _satdetails_on;
+
+
+/** VARIABLES FOR MAINTAINING STATE OF THE CURRENT VIEW. */
+
+/** The "zoom" level defines the resolution of a pixel, from 0 to MAX_ZOOM.
+ * Each pixel in the current view is exactly (1 << _zoom) "units" wide. */
+extern gint _zoom; /* zoom level, from 0 to MAX_ZOOM. */
+extern Point _center; /* current center location, X. */
+
+extern gint _next_zoom;
+extern Point _next_center;
+extern gint _next_map_rotate_angle;
+extern GdkPixbuf *_redraw_wait_icon;
+extern GdkRectangle _redraw_wait_bounds;
+
+
+/** CACHED SCREEN INFORMATION THAT IS DEPENDENT ON THE CURRENT VIEW. */
+extern gint _screen_width_pixels;
+extern gint _screen_height_pixels;
+extern gint _screen_halfwidth_pixels;
+extern gint _screen_halfheight_pixels;
+
+
+/** The current track and route. */
+extern Path _track;
+extern Path _route;
+extern gint _track_index_last_saved;
+
+/** THE GdkGC OBJECTS USED FOR DRAWING. */
+extern GdkGC *_gc[COLORABLE_ENUM_COUNT];
+extern GdkColor _color[COLORABLE_ENUM_COUNT];
+
+/** BANNERS. */
+extern GtkWidget *_connect_banner;
+extern GtkWidget *_fix_banner;
+extern GtkWidget *_waypoint_banner;
+extern GtkWidget *_download_banner;
+
+/** DOWNLOAD PROGRESS. */
+extern GMutex *_mapdb_mutex;
+extern GMutex *_mouse_mutex;
+extern volatile gint _num_downloads;
+extern gint _curr_download;
+extern GHashTable *_mut_exists_table;
+extern GTree *_mut_priority_tree;
+extern GMutex *_mut_priority_mutex;
+extern GThreadPool *_mut_thread_pool;
+extern GThreadPool *_mrt_thread_pool;
+
+/** CONFIGURATION INFORMATION. */
+extern GpsRcvrInfo _gri;
+extern ConnState _gps_state;
+extern gchar *_route_dir_uri;
+extern gchar *_track_file_uri;
+extern CenterMode _center_mode;
+extern gboolean _center_rotate;
+extern gboolean _fullscreen;
+extern gboolean _enable_gps;
+extern gboolean _gps_info;
+extern gchar *_route_dl_url;
+extern gint _route_dl_radius;
+extern gchar *_poi_dl_url;
+extern gint _show_paths;
+extern gboolean _show_zoomlevel;
+extern gboolean _show_scale;
+extern gboolean _show_comprose;
+extern gboolean _show_velvec;
+extern gboolean _show_poi;
+extern gboolean _auto_download;
+extern gint _auto_download_precache;
+extern gint _lead_ratio;
+extern gboolean _lead_is_fixed;
+extern gint _center_ratio;
+extern gint _draw_width;
+extern gint _rotate_sens;
+extern RotateDir _rotate_dir;
+extern gint _announce_notice_ratio;
+extern gboolean _enable_voice;
+extern GSList *_loc_list;
+extern GtkListStore *_loc_model;
+extern UnitType _units;
+extern CustomAction _action[CUSTOM_KEY_ENUM_COUNT];
+extern gint _degformat;
+extern gboolean _speed_limit_on;
+extern gint _speed_limit;
+extern gboolean _speed_excess;
+extern SpeedLocation _speed_location;
+extern UnblankOption _unblank_option;
+extern InfoFontSize _info_font_size;
+
+extern GList *_repo_list;
+extern RepoData *_curr_repo;
+
+/** POI */
+extern gchar *_poi_db_filename;
+extern gchar *_poi_db_dirname;
+extern gint _poi_zoom;
+extern gboolean _poi_enabled;
+
+/** The singleton auto-route-download data. */
+extern AutoRouteDownloadData _autoroute_data;
+
+
+/*********************
+ * BELOW: MENU ITEMS *
+ *********************/
+
+/* Menu items for the "Route" submenu. */
+extern GtkWidget *_menu_route_open_item;
+extern GtkWidget *_menu_route_download_item;
+extern GtkWidget *_menu_route_save_item;
+extern GtkWidget *_menu_route_distnext_item;
+extern GtkWidget *_menu_route_distlast_item;
+extern GtkWidget *_menu_route_reset_item;
+extern GtkWidget *_menu_route_clear_item;
+
+/* Menu items for the "Track" submenu. */
+extern GtkWidget *_menu_track_open_item;
+extern GtkWidget *_menu_track_save_item;
+extern GtkWidget *_menu_track_insert_break_item;
+extern GtkWidget *_menu_track_insert_mark_item;
+extern GtkWidget *_menu_track_distlast_item;
+extern GtkWidget *_menu_track_distfirst_item;
+extern GtkWidget *_menu_track_clear_item;
+
+/* Menu items for the "POI" submenu. */
+extern GtkWidget *_menu_poi_item;
+extern GtkWidget *_menu_poi_import_item;
+extern GtkWidget *_menu_poi_download_item;
+extern GtkWidget *_menu_poi_browse_item;
+extern GtkWidget *_menu_poi_categories_item;
+
+/* Menu items for the "Maps" submenu. */
+extern GtkWidget *_menu_maps_submenu;
+extern GtkWidget *_menu_maps_mapman_item;
+extern GtkWidget *_menu_maps_repoman_item;
+extern GtkWidget *_menu_maps_auto_download_item;
+
+/* Menu items for the "View" submenu. */
+extern GtkWidget *_menu_view_zoom_in_item;
+extern GtkWidget *_menu_view_zoom_out_item;
+
+extern GtkWidget *_menu_view_rotate_clock_item;
+extern GtkWidget *_menu_view_rotate_counter_item;
+extern GtkWidget *_menu_view_rotate_reset_item;
+extern GtkWidget *_menu_view_rotate_auto_item;
+
+extern GtkWidget *_menu_view_pan_up_item;
+extern GtkWidget *_menu_view_pan_down_item;
+extern GtkWidget *_menu_view_pan_left_item;
+extern GtkWidget *_menu_view_pan_right_item;
+extern GtkWidget *_menu_view_pan_north_item;
+extern GtkWidget *_menu_view_pan_south_item;
+extern GtkWidget *_menu_view_pan_west_item;
+extern GtkWidget *_menu_view_pan_east_item;
+
+extern GtkWidget *_menu_view_fullscreen_item;
+
+extern GtkWidget *_menu_view_show_zoomlevel_item;
+extern GtkWidget *_menu_view_show_scale_item;
+extern GtkWidget *_menu_view_show_comprose_item;
+extern GtkWidget *_menu_view_show_routes_item;
+extern GtkWidget *_menu_view_show_tracks_item;
+extern GtkWidget *_menu_view_show_velvec_item;
+extern GtkWidget *_menu_view_show_poi_item;
+
+extern GtkWidget *_menu_view_ac_latlon_item;
+extern GtkWidget *_menu_view_ac_lead_item;
+extern GtkWidget *_menu_view_ac_none_item;
+
+extern GtkWidget *_menu_view_goto_latlon_item;
+extern GtkWidget *_menu_view_goto_address_item;
+extern GtkWidget *_menu_view_goto_gps_item;
+extern GtkWidget *_menu_view_goto_nextway_item;
+extern GtkWidget *_menu_view_goto_nearpoi_item;
+
+/* Menu items for the "GPS" submenu. */
+extern GtkWidget *_menu_enable_gps_item;
+extern GtkWidget *_menu_gps_show_info_item;
+extern GtkWidget *_menu_gps_details_item;
+extern GtkWidget *_menu_gps_reset_item;
+
+/* Menu items for the other menu items. */
+extern GtkWidget *_menu_settings_item;
+extern GtkWidget *_menu_help_item;
+extern GtkWidget *_menu_about_item;
+extern GtkWidget *_menu_close_item;
+
+/*********************
+ * ABOVE: MENU ITEMS *
+ *********************/
+
+
+/*****************************
+ * BELOW: CONTEXT MENU ITEMS *
+ *****************************/
+
+extern gboolean _mouse_is_dragging;
+extern gboolean _mouse_is_down;
+extern gint _cmenu_position_x;
+extern gint _cmenu_position_y;
+
+/* Menu items for the "Location" context menu. */
+extern GtkWidget *_cmenu_loc_show_latlon_item;
+extern GtkWidget *_cmenu_loc_route_to_item;
+extern GtkWidget *_cmenu_loc_distance_to_item;
+extern GtkWidget *_cmenu_loc_download_poi_item;
+extern GtkWidget *_cmenu_loc_browse_poi_item;
+extern GtkWidget *_cmenu_loc_add_route_item;
+extern GtkWidget *_cmenu_loc_add_way_item;
+extern GtkWidget *_cmenu_loc_add_poi_item;
+extern GtkWidget *_cmenu_loc_set_gps_item;
+
+/* Menu items for the "Waypoint" context menu. */
+extern GtkWidget *_cmenu_way_show_latlon_item;
+extern GtkWidget *_cmenu_way_show_desc_item;
+extern GtkWidget *_cmenu_way_clip_latlon_item;
+extern GtkWidget *_cmenu_way_clip_desc_item;
+extern GtkWidget *_cmenu_way_route_to_item;
+extern GtkWidget *_cmenu_way_distance_to_item;
+extern GtkWidget *_cmenu_way_delete_item;
+extern GtkWidget *_cmenu_way_add_poi_item;
+extern GtkWidget *_cmenu_way_goto_nextway_item;
+
+/* Menu items for the "POI" context menu. */
+extern GtkWidget *_cmenu_poi_submenu;
+extern GtkWidget *_cmenu_poi_edit_poi_item;
+extern GtkWidget *_cmenu_poi_route_to_item;
+extern GtkWidget *_cmenu_poi_distance_to_item;
+extern GtkWidget *_cmenu_poi_add_route_item;
+extern GtkWidget *_cmenu_poi_add_way_item;
+extern GtkWidget *_cmenu_poi_goto_nearpoi_item;
+
+/*****************************
+ * ABOVE: CONTEXT MENU ITEMS *
+ *****************************/
+
+#endif /* ifndef MAEMO_MAPPER_DATA_H */
+
diff --git a/src/defines.h b/src/defines.h
new file mode 100644 (file)
index 0000000..a287a12
--- /dev/null
@@ -0,0 +1,381 @@
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAEMO_MAPPER_DEFINES
+#define MAEMO_MAPPER_DEFINES
+
+#include <libintl.h>
+
+#define _(String) gettext(String)
+
+#ifndef DEBUG
+#define printf(...)
+#endif
+
+/* Set the below if to determine whether to get verbose output. */
+#if 1
+#define vprintf printf
+#else
+#define vprintf(...)
+#endif
+
+#define BOUND(x, a, b) { \
+    if((x) < (a)) \
+        (x) = (a); \
+    else if((x) > (b)) \
+        (x) = (b); \
+}
+
+#define PI   (3.14159265358979323846f)
+
+#define EARTH_RADIUS (3440.06479f)
+
+/* #define MAPDB_SQLITE */
+
+/** MAX_ZOOM defines the largest map zoom level we will download.
+ * (MAX_ZOOM - 1) is the largest map zoom level that the user can zoom to.
+ */
+#define MIN_ZOOM (0)
+#define MAX_ZOOM (16)
+
+#define TILE_SIZE_PIXELS (256)
+#define TILE_HALFDIAG_PIXELS (181)
+#define TILE_SIZE_P2 (8)
+
+#define ARRAY_CHUNK_SIZE (1024)
+
+#define BUFFER_SIZE (2048)
+
+#define NUM_DOWNLOAD_THREADS (4)
+#define MAX_PIXBUF_DUP_SIZE (137)
+#define WORLD_SIZE_UNITS (2 << (MAX_ZOOM + TILE_SIZE_P2))
+
+#define HOURGLASS_SEPARATION (7)
+
+#define deg2rad(deg) ((deg) * (PI / 180.f))
+#define rad2deg(rad) ((rad) * (180.f / PI))
+
+#define tile2pixel(TILE) ((TILE) << TILE_SIZE_P2)
+#define pixel2tile(PIXEL) ((PIXEL) >> TILE_SIZE_P2)
+#define tile2unit(TILE) ((TILE) << (TILE_SIZE_P2 + _zoom))
+#define unit2tile(unit) ((unit) >> (TILE_SIZE_P2 + _zoom))
+#define tile2zunit(TILE, ZOOM) ((TILE) << (TILE_SIZE_P2 + (ZOOM)))
+#define unit2ztile(unit, ZOOM) ((unit) >> (TILE_SIZE_P2 + (ZOOM)))
+
+#define pixel2unit(PIXEL) ((PIXEL) << _zoom)
+#define unit2pixel(PIXEL) ((PIXEL) >> _zoom)
+#define pixel2zunit(PIXEL, ZOOM) ((PIXEL) << (ZOOM))
+#define unit2zpixel(PIXEL, ZOOM) ((PIXEL) >> (ZOOM))
+
+#define unit2buf_full(UNITX, UNITY, BUFX, BUFY, CENTER, MATRIX) { \
+    gfloat fdevx, fdevy; \
+    gdk_pixbuf_rotate_vector(&fdevx, &fdevy, (MATRIX), \
+            (gint)((UNITX) - (CENTER).unitx), \
+            (gint)((UNITY) - (CENTER).unity)); \
+    (BUFX) = unit2pixel((gint)(fdevx)) + _screen_halfwidth_pixels; \
+    (BUFY) = unit2pixel((gint)(fdevy)) + _screen_halfheight_pixels; \
+}
+
+#define unit2buf(UNITX, UNITY, BUFX, BUFY) \
+    (unit2buf_full(UNITX, UNITY, BUFX, BUFY, _center, _map_rotate_matrix))
+
+#define pixel2buf_full(PIXELX, PIXELY, BUFX, BUFY, CENTER, ZOOM, MATRIX) { \
+    gfloat fdevx, fdevy; \
+    gdk_pixbuf_rotate_vector(&fdevx, &fdevy, MATRIX, \
+            (gint)((PIXELX) - unit2zpixel((CENTER).unitx, (ZOOM))), \
+            (gint)((PIXELY) - unit2zpixel((CENTER).unity, (ZOOM)))); \
+    (BUFX) = fdevx + _screen_halfwidth_pixels; \
+    (BUFY) = fdevy + _screen_halfheight_pixels; \
+}
+
+#define pixel2buf(PIXELX, PIXELY, BUFX, BUFY) \
+    (pixel2buf_full(PIXELX, PIXELY, BUFX, BUFY, _center, _zoom, \
+                    _map_rotate_matrix))
+
+
+#define unit2screen_full(UNITX, UNITY, SCREENX, SCREENY, CENTER, MATRIX) { \
+    unit2buf_full(UNITX, UNITY, SCREENX, SCREENY, CENTER, MATRIX); \
+    (SCREENX) = (SCREENX) + _map_offset_devx; \
+    (SCREENY) = (SCREENY) + _map_offset_devy; \
+}
+
+#define unit2screen(UNITX, UNITY, SCREENX, SCREENY) \
+    (unit2screen_full(UNITX, UNITY, SCREENX, SCREENY, _center, \
+                      _map_rotate_matrix))
+
+#define pixel2screen_full(PIXELX, PIXELY, SCREENX, SCREENY, CENTER, MATRIX) { \
+    pixel2buf_full(PIXELX, PIXELY, SCREENX, SCREENY, CENTER, ZOOM, MATRIX); \
+    (SCREENX) = (SCREENX) + _map_offset_devx; \
+    (SCREENY) = (SCREENY) + _map_offset_devy; \
+}
+
+#define pixel2screen(PIXELX, PIXELY, SCREENX, SCREENY) \
+    (pixel2screen_full(PIXELX, PIXELY, SCREENX, SCREENY, _center, \
+                       _map_rotate_matrix))
+
+#define buf2unit_full(BUFX, BUFY, UNITX, UNITY, CENTER, MATRIX) { \
+    gfloat funitx, funity; \
+    gdk_pixbuf_rotate_vector(&funitx, &funity, MATRIX, \
+            pixel2unit((gint)((BUFX) - _screen_halfwidth_pixels)), \
+            pixel2unit((gint)((BUFY) - _screen_halfheight_pixels))); \
+    (UNITX) = funitx + CENTER.unitx; \
+    (UNITY) = funity + CENTER.unity; \
+}
+
+#define buf2unit(BUFX, BUFY, UNITX, UNITY) \
+    (buf2unit_full(BUFX, BUFY, UNITX, UNITY, _center, _map_reverse_matrix))
+
+#define buf2pixel_full(BUFX, BUFY, PIXELX, PIXELY, CENTER, MATRIX) { \
+    gfloat fpixelx, fpixely; \
+    gdk_pixbuf_rotate_vector(&fpixelx, &fpixely, MATRIX, \
+            (gint)(BUFX) - _screen_halfwidth_pixels, \
+            (gint)(BUFY) - _screen_halfheight_pixels); \
+    (PIXELX) = fpixelx + unit2pixel(CENTER.unitx); \
+    (PIXELY) = fpixely + unit2pixel(CENTER.unity); \
+}
+
+#define buf2pixel(BUFX, BUFY, PIXELX, PIXELY) \
+    (buf2pixel_full(BUFX, BUFY, PIXELX, PIXELY, _center, _map_reverse_matrix))
+
+#define screen2unit_full(SCREENX, SCREENY, UNITX, UNITY, CENTER, MATRIX) ( \
+    buf2unit_full((SCREENX) - _map_offset_devx, (SCREENY) - _map_offset_devy, \
+        UNITX, UNITY, CENTER, MATRIX))
+
+#define screen2unit(SCREENX, SCREENY, UNITX, UNITY) \
+    (screen2unit_full(SCREENX, SCREENY, UNITX, UNITY, _center, \
+                      _map_reverse_matrix))
+
+#define screen2pixel_full(SCREENX, SCREENY, PIXELX, PIXELY, CENTER, MATRIX) ( \
+    buf2pixel_full((SCREENX) - _map_offset_devx, (SCREENY) - _map_offset_devy,\
+        PIXELX, PIXELY, CENTER, MATRIX))
+
+#define screen2pixel(SCREENX, SCREENY, PIXELX, PIXELY) ( \
+    screen2pixel_full(SCREENX, SCREENY, PIXELX, PIXELY, \
+        _center,_map_reverse_matrix))
+
+/* Pans are done 64 pixels at a time. */
+#define PAN_PIXELS (64)
+#define ROTATE_DEGREES (30)
+
+#define INITIAL_DOWNLOAD_RETRIES (3)
+
+#define GCONF_KEY_PREFIX "/apps/maemo/maemo-mapper"
+#define GCONF_KEY_GPS_RCVR_TYPE GCONF_KEY_PREFIX"/gps_rcvr_type"
+#define GCONF_KEY_GPS_BT_MAC GCONF_KEY_PREFIX"/receiver_mac"
+#define GCONF_KEY_GPS_BT_FILE GCONF_KEY_PREFIX"/receiver_file"
+#define GCONF_KEY_GPS_GPSD_HOST GCONF_KEY_PREFIX"/gps_gpsd_host"
+#define GCONF_KEY_GPS_GPSD_PORT GCONF_KEY_PREFIX"/gps_gpsd_port"
+#define GCONF_KEY_GPS_FILE_PATH GCONF_KEY_PREFIX"/gps_file_path"
+#define GCONF_KEY_AUTO_DOWNLOAD GCONF_KEY_PREFIX"/auto_download"
+#define GCONF_KEY_AUTO_DOWNLOAD_PRECACHE \
+                                      GCONF_KEY_PREFIX"/auto_download_precache"
+#define GCONF_KEY_CENTER_SENSITIVITY GCONF_KEY_PREFIX"/center_sensitivity"
+#define GCONF_KEY_ANNOUNCE_NOTICE GCONF_KEY_PREFIX"/announce_notice"
+#define GCONF_KEY_ROTATE_SENSITIVITY GCONF_KEY_PREFIX"/rotate_sensitivity"
+#define GCONF_KEY_ROTATE_DIR GCONF_KEY_PREFIX"/rotate_direction"
+#define GCONF_KEY_DRAW_WIDTH GCONF_KEY_PREFIX"/draw_width"
+#define GCONF_KEY_ENABLE_VOICE GCONF_KEY_PREFIX"/enable_voice"
+#define GCONF_KEY_VOICE_SPEED GCONF_KEY_PREFIX"/voice_speed"
+#define GCONF_KEY_VOICE_PITCH GCONF_KEY_PREFIX"/voice_pitch"
+#define GCONF_KEY_FULLSCREEN GCONF_KEY_PREFIX"/fullscreen"
+#define GCONF_KEY_UNITS GCONF_KEY_PREFIX"/units"
+#define GCONF_KEY_SPEED_LIMIT_ON GCONF_KEY_PREFIX"/speed_limit_on"
+#define GCONF_KEY_SPEED_LIMIT GCONF_KEY_PREFIX"/speed_limit"
+#define GCONF_KEY_SPEED_LOCATION GCONF_KEY_PREFIX"/speed_location"
+#define GCONF_KEY_UNBLANK_SIZE GCONF_KEY_PREFIX"/unblank_option"
+#define GCONF_KEY_INFO_FONT_SIZE GCONF_KEY_PREFIX"/info_font_size"
+
+#define GCONF_KEY_POI_DB GCONF_KEY_PREFIX"/poi_db"
+#define GCONF_KEY_POI_ZOOM GCONF_KEY_PREFIX"/poi_zoom"
+
+#define GCONF_KEY_AUTOCENTER_MODE GCONF_KEY_PREFIX"/autocenter_mode"
+#define GCONF_KEY_AUTOCENTER_ROTATE GCONF_KEY_PREFIX"/autocenter_rotate"
+#define GCONF_KEY_LEAD_AMOUNT GCONF_KEY_PREFIX"/lead_amount"
+#define GCONF_KEY_LEAD_IS_FIXED GCONF_KEY_PREFIX"/lead_is_fixed"
+#define GCONF_KEY_LAST_LAT GCONF_KEY_PREFIX"/last_latitude"
+#define GCONF_KEY_LAST_LON GCONF_KEY_PREFIX"/last_longitude"
+#define GCONF_KEY_LAST_ALT GCONF_KEY_PREFIX"/last_altitude"
+#define GCONF_KEY_LAST_SPEED GCONF_KEY_PREFIX"/last_speed"
+#define GCONF_KEY_LAST_HEADING GCONF_KEY_PREFIX"/last_heading"
+#define GCONF_KEY_LAST_TIME GCONF_KEY_PREFIX"/last_timestamp"
+#define GCONF_KEY_CENTER_LAT GCONF_KEY_PREFIX"/center_latitude"
+#define GCONF_KEY_CENTER_LON GCONF_KEY_PREFIX"/center_longitude"
+#define GCONF_KEY_CENTER_ANGLE GCONF_KEY_PREFIX"/center_angle"
+#define GCONF_KEY_ZOOM GCONF_KEY_PREFIX"/zoom"
+#define GCONF_KEY_ROUTEDIR GCONF_KEY_PREFIX"/route_directory"
+#define GCONF_KEY_TRACKFILE GCONF_KEY_PREFIX"/track_file"
+#define GCONF_KEY_SHOWZOOMLEVEL GCONF_KEY_PREFIX"/show_zoomlevel"
+#define GCONF_KEY_SHOWSCALE GCONF_KEY_PREFIX"/show_scale"
+#define GCONF_KEY_SHOWCOMPROSE GCONF_KEY_PREFIX"/show_comprose"
+#define GCONF_KEY_SHOWTRACKS GCONF_KEY_PREFIX"/show_tracks"
+#define GCONF_KEY_SHOWROUTES GCONF_KEY_PREFIX"/show_routes"
+#define GCONF_KEY_SHOWVELVEC GCONF_KEY_PREFIX"/show_velocity_vector"
+#define GCONF_KEY_SHOWPOIS GCONF_KEY_PREFIX"/show_poi"
+#define GCONF_KEY_ENABLE_GPS GCONF_KEY_PREFIX"/enable_gps"
+#define GCONF_KEY_ROUTE_LOCATIONS GCONF_KEY_PREFIX"/route_locations"
+#define GCONF_KEY_REPOSITORIES GCONF_KEY_PREFIX"/repositories"
+#define GCONF_KEY_CURRREPO GCONF_KEY_PREFIX"/curr_repo"
+#define GCONF_KEY_GPS_INFO GCONF_KEY_PREFIX"/gps_info"
+#define GCONF_KEY_ROUTE_DL_URL GCONF_KEY_PREFIX"/route_dl_url"
+#define GCONF_KEY_ROUTE_DL_RADIUS GCONF_KEY_PREFIX"/route_dl_radius"
+#define GCONF_KEY_POI_DL_URL GCONF_KEY_PREFIX"/poi_dl_url"
+#define GCONF_KEY_DEG_FORMAT GCONF_KEY_PREFIX"/deg_format"
+
+#define CONFIG_DIR_NAME "~/.maemo-mapper/"
+#define CONFIG_PATH_DB_FILE "paths.db"
+
+#define REPO_DEFAULT_NAME "OpenStreet"
+#define REPO_DEFAULT_CACHE_BASE "~/MyDocs/.documents/Maps/"
+#define REPO_DEFAULT_CACHE_DIR REPO_DEFAULT_CACHE_BASE"OpenStreet.db"
+#define REPO_DEFAULT_MAP_URI "http://tile.openstreetmap.org/%0d/%d/%d.png"
+#define REPO_DEFAULT_DL_ZOOM_STEPS (2)
+#define REPO_DEFAULT_VIEW_ZOOM_STEPS (1)
+
+#define XML_DATE_FORMAT "%FT%T"
+
+#define HELP_ID_PREFIX "help_maemomapper_"
+#define HELP_ID_INTRO HELP_ID_PREFIX"intro"
+#define HELP_ID_GETSTARTED HELP_ID_PREFIX"getstarted"
+#define HELP_ID_ABOUT HELP_ID_PREFIX"about"
+#define HELP_ID_SETTINGS HELP_ID_PREFIX"settings"
+#define HELP_ID_REPOMAN HELP_ID_PREFIX"repoman"
+#define HELP_ID_MAPMAN HELP_ID_PREFIX"mapman"
+#define HELP_ID_DOWNROUTE HELP_ID_PREFIX"downroute"
+#define HELP_ID_DOWNPOI HELP_ID_PREFIX"downpoi"
+#define HELP_ID_BROWSEPOI HELP_ID_PREFIX"browsepoi"
+#define HELP_ID_POILIST HELP_ID_PREFIX"poilist"
+#define HELP_ID_POICAT HELP_ID_PREFIX"poicat"
+
+#define MERCATOR_SPAN (-6.28318377773622f)
+#define MERCATOR_TOP (3.14159188886811f)
+#define latlon2unit(lat, lon, unitx, unity) { \
+    gfloat tmp; \
+    unitx = (lon + 180.f) * (WORLD_SIZE_UNITS / 360.f) + 0.5f; \
+    tmp = sinf(deg2rad(lat)); \
+    unity = 0.5f + (WORLD_SIZE_UNITS / MERCATOR_SPAN) \
+        * (logf((1.f + tmp) / (1.f - tmp)) * 0.5f - MERCATOR_TOP); \
+}
+
+#define unit2latlon(unitx, unity, lat, lon) { \
+    (lon) = ((unitx) * (360.f / WORLD_SIZE_UNITS)) - 180.f; \
+    (lat) = (360.f * (atanf(expf(((unity) \
+                                  * (MERCATOR_SPAN / WORLD_SIZE_UNITS)) \
+                     + MERCATOR_TOP)))) * (1.f / PI) - 90.f; \
+}
+
+#define MACRO_PATH_INIT(path) { \
+    (path).head = (path).tail = g_new(Point, ARRAY_CHUNK_SIZE); \
+    *((path).tail) = _point_null; \
+    (path).cap = (path).head + ARRAY_CHUNK_SIZE; \
+    (path).whead = g_new(WayPoint, ARRAY_CHUNK_SIZE); \
+    (path).wtail = (path).whead - 1; \
+    (path).wcap = (path).whead + ARRAY_CHUNK_SIZE; \
+}
+
+#define MACRO_PATH_FREE(path) if((path).head) { \
+    WayPoint *curr; \
+    g_free((path).head); \
+    (path).head = (path).tail = (path).cap = NULL; \
+    for(curr = (path).whead - 1; curr++ != (path).wtail; ) \
+        g_free(curr->desc); \
+    g_free((path).whead); \
+    (path).whead = (path).wtail = (path).wcap = NULL; \
+}
+
+#define MACRO_PATH_INCREMENT_TAIL(route) { \
+    if(++(route).tail == (route).cap) \
+        path_resize(&(route), (route).cap - (route).head + ARRAY_CHUNK_SIZE);\
+}
+
+#define MACRO_PATH_INCREMENT_WTAIL(route) { \
+    if(++(route).wtail == (route).wcap) \
+        path_wresize(&(route), \
+                (route).wcap - (route).whead + ARRAY_CHUNK_SIZE); \
+}
+
+#define DISTANCE_SQUARED(a, b) \
+   ((guint64)((((gint64)(b).unitx)-(a).unitx)*(((gint64)(b).unitx)-(a).unitx))\
+  + (guint64)((((gint64)(b).unity)-(a).unity)*(((gint64)(b).unity)-(a).unity)))
+
+#define MACRO_QUEUE_DRAW_AREA() \
+    gtk_widget_queue_draw_area( \
+            _map_widget, \
+            0, 0, \
+            _screen_width_pixels, \
+            _screen_height_pixels)
+
+/* Render all on-map metadata an annotations, including POI and paths. */
+#define MACRO_MAP_RENDER_DATA() { \
+    if(_show_poi) \
+        map_render_poi(); \
+    if(_show_paths > 0) \
+        map_render_paths(); \
+}
+
+#define UNBLANK_SCREEN(MOVING, APPROACHING_WAYPOINT) { \
+    /* Check if we need to unblank the screen. */ \
+    switch(_unblank_option) \
+    { \
+        case UNBLANK_NEVER: \
+            break; \
+        case UNBLANK_WAYPOINT: \
+            if(APPROACHING_WAYPOINT) \
+            { \
+                printf("Unblanking screen...\n"); \
+                osso_display_state_on(_osso); \
+                osso_display_blanking_pause(_osso); \
+            } \
+            break; \
+        default: \
+        case UNBLANK_FULLSCREEN: \
+            if(!_fullscreen) \
+                break; \
+        case UNBLANK_WHEN_MOVING: \
+            if(!MOVING) \
+                break; \
+        case UNBLANK_WITH_GPS: \
+            printf("Unblanking screen...\n"); \
+            osso_display_state_on(_osso); \
+            osso_display_blanking_pause(_osso); \
+    } \
+}
+
+#define LL_FMT_LEN 20
+#define lat_format(A, B) deg_format((A), (B), 'S', 'N')
+#define lon_format(A, B) deg_format((A), (B), 'W', 'E')
+
+#define TRACKS_MASK 0x00000001
+#define ROUTES_MASK 0x00000002
+
+#define g_timeout_add(I, F, D) g_timeout_add_full(G_PRIORITY_DEFAULT_IDLE, \
+          (I), (F), (D), NULL)
+
+#define MACRO_BANNER_SHOW_INFO(A, S) { \
+    gchar *my_macro_buffer = g_markup_printf_escaped( \
+            "<span size='%s'>%s</span>", \
+            INFO_FONT_ENUM_TEXT[_info_font_size], (S)); \
+    hildon_banner_show_information_with_markup(A, NULL, my_macro_buffer); \
+    g_free(my_macro_buffer); \
+}
+
+#endif /* ifndef MAEMO_MAPPER_DEFINES */
diff --git a/src/display.c b/src/display.c
new file mode 100644 (file)
index 0000000..f3f5673
--- /dev/null
@@ -0,0 +1,2650 @@
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#define _GNU_SOURCE
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <osso-helplib.h>
+#include <hildon-widgets/hildon-note.h>
+#include <hildon-widgets/hildon-file-chooser-dialog.h>
+#include <hildon-widgets/hildon-banner.h>
+#include <hildon-widgets/hildon-system-sound.h>
+
+#include "types.h"
+#include "data.h"
+#include "defines.h"
+
+#include "display.h"
+#include "gdk-pixbuf-rotate.h"
+#include "gps.h"
+#include "maps.h"
+#include "path.h"
+#include "poi.h"
+#include "settings.h"
+#include "util.h"
+
+#define VELVEC_SIZE_FACTOR (4)
+
+static GtkWidget *_sat_details_panel = NULL;
+static GtkWidget *_sdi_lat = NULL;
+static GtkWidget *_sdi_lon = NULL;
+static GtkWidget *_sdi_spd = NULL;
+static GtkWidget *_sdi_alt = NULL;
+static GtkWidget *_sdi_hea = NULL;
+static GtkWidget *_sdi_tim = NULL;
+static GtkWidget *_sdi_vie = NULL;
+static GtkWidget *_sdi_use = NULL;
+static GtkWidget *_sdi_fix = NULL;
+static GtkWidget *_sdi_fqu = NULL;
+static GtkWidget *_sdi_msp = NULL;
+static gboolean _redraw_count = 0;
+
+static gint _mark_bufx1 = -1;
+static gint _mark_bufx2 = -1;
+static gint _mark_bufy1 = -1;
+static gint _mark_bufy2 = -1;
+static gint _mark_minx = -1;
+static gint _mark_miny = -1;
+static gint _mark_width = -1;
+static gint _mark_height = -1;
+static GdkRectangle _scale_rect = { 0, 0, 0, 0};
+static GdkRectangle _zoom_rect = { 0, 0, 0, 0};
+static gint _dl_errors = 0;
+
+
+/** Pango stuff. */
+GdkRectangle _comprose_rect = { 0, 0, 0, 0};
+PangoLayout *_scale_layout = NULL;
+PangoLayout *_zoom_layout = NULL;
+PangoLayout *_comprose_layout = NULL;
+GdkGC *_speed_limit_gc1 = NULL;
+GdkGC *_speed_limit_gc2 = NULL;
+PangoLayout *_speed_limit_layout = NULL;
+PangoLayout *_sat_panel_layout = NULL;
+PangoLayout *_heading_panel_layout = NULL;
+PangoFontDescription *_heading_panel_fontdesc = NULL;
+GdkGC *_sat_info_gc1 = NULL;
+GdkGC *_sat_info_gc2 = NULL;
+PangoLayout *_sat_info_layout = NULL;
+PangoLayout *_sat_details_layout = NULL;
+PangoLayout *_sat_details_expose_layout = NULL;
+
+#define SCALE_WIDTH (100)
+
+static gboolean
+speed_excess(void)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+    if(!_speed_excess)
+        return FALSE;
+
+    hildon_play_system_sound(
+        "/usr/share/sounds/ui-information_note.wav");
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static void
+speed_limit(void)
+{
+    GdkGC *gc;
+    gfloat cur_speed;
+    gchar *buffer;
+    static gint x = 0, y = 0, width = 0, height = 0;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    cur_speed = _gps.speed * UNITS_CONVERT[_units];
+
+    if(cur_speed > _speed_limit)
+    {
+        gc = _speed_limit_gc1;
+        if(!_speed_excess)
+        {
+            _speed_excess = TRUE;
+            g_timeout_add(5000, (GSourceFunc)speed_excess, NULL);
+        }
+    }
+    else
+    {
+        gc = _speed_limit_gc2;
+        _speed_excess = FALSE;
+    }
+
+    /* remove previous number */
+    if (width != 0 && height != 0) {
+      gtk_widget_queue_draw_area (_map_widget,
+                                 x - 5,
+                                 y - 5,
+                                 width + 10,
+                                 height + 10);
+      gdk_window_process_all_updates();
+    }
+
+    buffer = g_strdup_printf("%0.0f", cur_speed);
+    pango_layout_set_text(_speed_limit_layout, buffer, -1);
+
+
+    pango_layout_get_pixel_size(_speed_limit_layout, &width, &height);
+
+    switch (_speed_location)
+    {
+        case SPEED_LOCATION_TOP_RIGHT:
+            x = _map_widget->allocation.width - 10 - width;
+            y = 5;
+            break;
+        case SPEED_LOCATION_BOTTOM_RIGHT:
+            x = _map_widget->allocation.width - 10 - width;
+            y = _map_widget->allocation.height - 10 - height;
+            break;
+        case SPEED_LOCATION_BOTTOM_LEFT:
+            x = 10;
+            y = _map_widget->allocation.height - 10 - height;
+            break;
+        default:
+            x = 10;
+            y = 10;
+            break;
+    }
+
+    gdk_draw_layout(_map_widget->window,
+        gc,
+        x, y,
+        _speed_limit_layout);
+    g_free(buffer);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+gboolean
+gps_display_details(void)
+{
+    gchar *buffer, litbuf[16];
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(_gps.fix < 2)
+    {
+        /* no fix no fun */
+        gtk_label_set_label(GTK_LABEL(_sdi_lat), " --- ");
+        gtk_label_set_label(GTK_LABEL(_sdi_lon), " --- ");
+        gtk_label_set_label(GTK_LABEL(_sdi_spd), " --- ");
+        gtk_label_set_label(GTK_LABEL(_sdi_alt), " --- ");
+        gtk_label_set_label(GTK_LABEL(_sdi_hea), " --- ");
+        gtk_label_set_label(GTK_LABEL(_sdi_tim), " --:--:-- ");
+    }
+    else
+    {
+        gfloat speed = _gps.speed * UNITS_CONVERT[_units];
+
+        /* latitude */
+        lat_format(_gps.lat, litbuf);
+        gtk_label_set_label(GTK_LABEL(_sdi_lat), litbuf);
+
+        /* longitude */
+        lon_format(_gps.lon, litbuf);
+        gtk_label_set_label(GTK_LABEL(_sdi_lon), litbuf);
+
+        /* speed */
+        switch(_units)
+        {
+            case UNITS_MI:
+                buffer = g_strdup_printf("%.1f mph", speed);
+                break;
+            case UNITS_NM:
+                buffer = g_strdup_printf("%.1f kn", speed);
+                break;
+            default:
+                buffer = g_strdup_printf("%.1f km/h", speed);
+                break;
+        }
+        gtk_label_set_label(GTK_LABEL(_sdi_spd), buffer);
+        g_free(buffer);
+
+        /* altitude */
+        switch(_units)
+        {
+            case UNITS_MI:
+            case UNITS_NM:
+                buffer = g_strdup_printf("%d ft",
+                        (gint)(_pos.altitude * 3.2808399f));
+                break;
+            default:
+                buffer = g_strdup_printf("%d m", _pos.altitude);
+                break;
+        }
+        gtk_label_set_label(GTK_LABEL(_sdi_alt), buffer);
+        g_free(buffer);
+
+        /* heading */
+        buffer = g_strdup_printf("%0.0f°", _gps.heading);
+        gtk_label_set_label(GTK_LABEL(_sdi_hea), buffer);
+        g_free(buffer);
+
+        /* local time */
+        strftime(litbuf, 15, "%X", localtime(&_pos.time));
+        gtk_label_set_label(GTK_LABEL(_sdi_tim), litbuf);
+    }
+
+    /* Sat in view */
+    buffer = g_strdup_printf("%d", _gps.satinview);
+    gtk_label_set_label(GTK_LABEL(_sdi_vie), buffer);
+    g_free(buffer);
+
+    /* Sat in use */
+    buffer = g_strdup_printf("%d", _gps.satinuse);
+    gtk_label_set_label(GTK_LABEL(_sdi_use), buffer);
+    g_free(buffer);
+
+    /* fix */
+    switch(_gps.fix)
+    {
+        case 2:
+        case 3: buffer = g_strdup_printf("%dD fix", _gps.fix); break;
+        default: buffer = g_strdup_printf("nofix"); break;
+    }
+    gtk_label_set_label(GTK_LABEL(_sdi_fix), buffer);
+    g_free(buffer);
+
+    if(_gps.fix == 1)
+        buffer = g_strdup("none");
+    else
+    {
+        switch (_gps.fixquality)
+        {
+            case 1 : buffer = g_strdup_printf(_("SPS")); break;
+            case 2 : buffer = g_strdup_printf(_("DGPS")); break;
+            case 3 : buffer = g_strdup_printf(_("PPS")); break;
+            case 4 : buffer = g_strdup_printf(_("Real Time Kinematic")); break;
+            case 5 : buffer = g_strdup_printf(_("Float RTK")); break;
+            case 6 : buffer = g_strdup_printf(_("Estimated")); break;
+            case 7 : buffer = g_strdup_printf(_("Manual")); break;
+            case 8 : buffer = g_strdup_printf(_("Simulation")); break;
+            default : buffer = g_strdup_printf(_("none")); break;
+        }
+    }
+    gtk_label_set_label(GTK_LABEL(_sdi_fqu), buffer);
+    g_free(buffer);
+
+    /* max speed */
+    {
+        gfloat maxspeed = _gps.maxspeed * UNITS_CONVERT[_units];
+
+        /* speed */
+        switch(_units)
+        {
+            case UNITS_MI:
+                buffer = g_strdup_printf("%.1f mph", maxspeed);
+                break;
+            case UNITS_NM:
+                buffer = g_strdup_printf("%.1f kn", maxspeed);
+                break;
+            default:
+                buffer = g_strdup_printf("%.1f km/h", maxspeed);
+                break;
+        }
+        gtk_label_set_label(GTK_LABEL(_sdi_msp), buffer);
+        g_free(buffer);
+    }
+
+    /* refresh sat panel */
+    gtk_widget_queue_draw_area(GTK_WIDGET(_sat_details_panel),
+        0, 0,
+        _sat_details_panel->allocation.width,
+        _sat_details_panel->allocation.height);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+void
+gps_display_data(void)
+{
+    gchar *buffer, litbuf[LL_FMT_LEN];
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(_gps.fix < 2)
+    {
+        /* no fix no fun */
+        gtk_label_set_label(GTK_LABEL(_text_lat), " --- ");
+        gtk_label_set_label(GTK_LABEL(_text_lon), " --- ");
+        gtk_label_set_label(GTK_LABEL(_text_speed), " --- ");
+        gtk_label_set_label(GTK_LABEL(_text_alt), " --- ");
+        gtk_label_set_label(GTK_LABEL(_text_time), " --:--:-- ");
+    }
+    else
+    {
+        gfloat speed = _gps.speed * UNITS_CONVERT[_units];
+
+        /* latitude */
+        lat_format(_gps.lat, litbuf);
+        gtk_label_set_label(GTK_LABEL(_text_lat), litbuf);
+
+        /* longitude */
+        lon_format(_gps.lon, litbuf);
+        gtk_label_set_label(GTK_LABEL(_text_lon), litbuf);
+
+        /* speed */
+        switch(_units)
+        {
+            case UNITS_MI:
+                buffer = g_strdup_printf("Spd: %.1f mph", speed);
+                break;
+            case UNITS_NM:
+                buffer = g_strdup_printf("Spd: %.1f kn", speed);
+                break;
+            default:
+                buffer = g_strdup_printf("Spd: %.1f km/h", speed);
+                break;
+        }
+        gtk_label_set_label(GTK_LABEL(_text_speed), buffer);
+        g_free(buffer);
+
+        /* altitude */
+        switch(_units)
+        {
+            case UNITS_MI:
+            case UNITS_NM:
+                buffer = g_strdup_printf("Alt: %d ft",
+                        (gint)(_pos.altitude * 3.2808399f));
+                break;
+            default:
+                buffer = g_strdup_printf("Alt: %d m", _pos.altitude);
+        }
+        gtk_label_set_label(GTK_LABEL(_text_alt), buffer);
+        g_free(buffer);
+
+        /* local time */
+        strftime(litbuf, 15, "%X", localtime(&_pos.time));
+        gtk_label_set_label(GTK_LABEL(_text_time), litbuf);
+    }
+
+    /* refresh sat panel */
+    gtk_widget_queue_draw_area(GTK_WIDGET(_sat_panel),
+        0, 0,
+        _sat_panel->allocation.width,
+        _sat_panel->allocation.height);
+
+    /* refresh heading panel*/
+    gtk_widget_queue_draw_area(GTK_WIDGET(_heading_panel),
+        0, 0,
+        _heading_panel->allocation.width,
+        _heading_panel->allocation.height);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+    return;
+}
+
+void
+gps_hide_text(void)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    /* Clear gps data */
+    _gps.fix = 1;
+    _gps.satinuse = 0;
+    _gps.satinview = 0;
+
+    if(_gps_info)
+        gps_display_data();
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+void
+gps_show_info(void)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(_gps_info && _enable_gps)
+        gtk_widget_show_all(GTK_WIDGET(_gps_widget));
+    else
+    {
+        gps_hide_text();
+        gtk_widget_hide_all(GTK_WIDGET(_gps_widget));
+    }
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+static void
+draw_sat_info(GtkWidget *widget, gint x0, gint y0,
+        gint width, gint height, gboolean showsnr)
+{
+    GdkGC *gc;
+    gint step, i, j, snr_height, bymargin, xoffset, yoffset;
+    gint x, y, x1, y1;
+    gchar *tmp = NULL;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    xoffset = x0;
+    yoffset = y0;
+    /* Bootom margin - 12% */
+    bymargin = height * 0.88f;
+
+    /* Bottom line */
+    gdk_draw_line(widget->window,
+        widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+        xoffset + 5, yoffset + bymargin,
+        xoffset + width - 10 - 2, yoffset + bymargin);
+    gdk_draw_line(widget->window,
+        widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+        xoffset + 5, yoffset + bymargin - 1,
+        xoffset + width - 10 - 2, yoffset + bymargin - 1);
+
+    if(_gps.satinview > 0 )
+    {
+        /* Left margin - 5pix, Right margin - 5pix */
+        step = (width - 10) / _gps.satinview;
+
+        for(i = 0; i < _gps.satinview; i++)
+        {
+            /* Sat used or not */
+            gc = _sat_info_gc1;
+            for(j = 0; j < _gps.satinuse ; j++)
+            {
+                if(_gps.satforfix[j] == _gps_sat[i].prn)
+                {
+                    gc = _sat_info_gc2;
+                    break;
+                }
+            }
+
+            x = 5 + i * step;
+            snr_height = _gps_sat[i].snr * height * 0.78f / 100;
+            y = height * 0.1f + (height * 0.78f - snr_height);
+
+            /* draw sat rectangle... */
+            gdk_draw_rectangle(widget->window,
+                    gc,
+                    TRUE,
+                    xoffset + x,
+                    yoffset + y,
+                    step - 2,
+                    snr_height);
+
+            if(showsnr && _gps_sat[i].snr > 0)
+            {
+                /* ...snr.. */
+                tmp = g_strdup_printf("%02d", _gps_sat[i].snr);
+                pango_layout_set_text(_sat_info_layout, tmp, 2);
+                pango_layout_get_pixel_size(_sat_info_layout, &x1, &y1);
+                gdk_draw_layout(widget->window,
+                    widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+                    xoffset + x + ((step - 2) - x1)/2,
+                    yoffset + y - 15,
+                    _sat_info_layout);
+                g_free(tmp);
+            }
+
+            /* ...and sat number */
+            tmp = g_strdup_printf("%02d", _gps_sat[i].prn);
+            pango_layout_set_text(_sat_info_layout, tmp, 2);
+            pango_layout_get_pixel_size(_sat_info_layout, &x1, &y1);
+            gdk_draw_layout(widget->window,
+                widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+                xoffset + x + ((step - 2) - x1)/2 ,
+                yoffset + bymargin + 1,
+                _sat_info_layout);
+            g_free(tmp);
+        }
+    }
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+    return;
+}
+
+static void
+draw_sat_details(GtkWidget *widget, gint x0, gint y0,
+        gint width, gint height)
+{
+    gint i, j, x, y, size, halfsize, xoffset, yoffset;
+    gint x1, y1;
+    gfloat tmp;
+    GdkColor color;
+    GdkGC *gc1, *gc2, *gc3, *gc;
+    gchar *buffer = NULL;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    size = MIN(width, height);
+    halfsize = size/2;
+    if(width > height)
+    {
+        xoffset = x0 + (width - height - 10) / 2;
+        yoffset = y0 + 5;
+    }
+    else
+    {
+        xoffset = x0 + 5;
+        yoffset = y0 + (height - width - 10) / 2;
+    }
+
+    /* 90 */
+    gdk_draw_arc(widget->window,
+            widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+            FALSE,
+            xoffset + 2, yoffset + 2, size - 4, size - 4,
+            0, 64 * 360);
+
+    /* 60 */
+    gdk_draw_arc(widget->window,
+            widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+            FALSE,
+            xoffset + size/6, yoffset + size/6,
+            size/6*4, size/6*4,
+            0, 64 * 360);
+
+    /* 30 */
+    gdk_draw_arc(widget->window,
+            widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+            FALSE,
+            xoffset + size/6*2, yoffset + size/6*2,
+            size/6*2, size/6*2,
+            0, 64 * 360);
+
+    gint line[12] = {0,30,60,90,120,150,180,210,240,270,300,330};
+
+    for(i = 0; i < 6; i++)
+    {
+        /* line */
+        tmp = deg2rad(line[i]);
+        gdk_draw_line(widget->window,
+            widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+            xoffset + halfsize + (halfsize -2) * sinf(tmp),
+            yoffset + halfsize - (halfsize -2) * cosf(tmp),
+            xoffset + halfsize - (halfsize -2) * sinf(tmp),
+            yoffset + halfsize + (halfsize -2) * cosf(tmp));
+    }
+
+    for(i = 0; i < 12; i++)
+    {
+        tmp = deg2rad(line[i]);
+        /* azimuth */
+        if(line[i] == 0)
+            buffer = g_strdup_printf("N");
+        else
+            buffer = g_strdup_printf("%d°", line[i]);
+        pango_layout_set_text(_sat_details_layout, buffer, -1);
+        pango_layout_get_pixel_size(_sat_details_layout, &x, &y);
+        gdk_draw_layout(widget->window,
+            widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+            (xoffset + halfsize + (halfsize - size/12) * sinf(tmp)) - x/2,
+            (yoffset + halfsize - (halfsize - size/12) * cosf(tmp)) - y/2,
+            _sat_details_layout);
+        g_free(buffer);
+    }
+
+    /* elevation 30 */
+    tmp = deg2rad(30);
+    buffer = g_strdup_printf("30°");
+    pango_layout_set_text(_sat_details_layout, buffer, -1);
+    pango_layout_get_pixel_size(_sat_details_layout, &x, &y);
+    gdk_draw_layout(widget->window,
+        widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+        (xoffset + halfsize + size/6*2 * sinf(tmp)) - x/2,
+        (yoffset + halfsize - size/6*2 * cosf(tmp)) - y/2,
+        _sat_details_layout);
+    g_free(buffer);
+
+    /* elevation 60 */
+    tmp = deg2rad(30);
+    buffer = g_strdup_printf("60°");
+    pango_layout_set_text(_sat_details_layout, buffer, -1);
+    pango_layout_get_pixel_size(_sat_details_layout, &x, &y);
+    gdk_draw_layout(widget->window,
+        widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+        (xoffset + halfsize + size/6 * sinf(tmp)) - x/2,
+        (yoffset + halfsize - size/6 * cosf(tmp)) - y/2,
+        _sat_details_layout);
+    g_free(buffer);
+
+    color.red = 0;
+    color.green = 0;
+    color.blue = 0;
+    gc1 = gdk_gc_new (widget->window);
+    gdk_gc_set_rgb_fg_color (gc1, &color);
+
+    color.red = 0;
+    color.green = 0;
+    color.blue = 0xffff;
+    gc2 = gdk_gc_new (widget->window);
+    gdk_gc_set_rgb_fg_color (gc2, &color);
+
+    color.red = 0xffff;
+    color.green = 0xffff;
+    color.blue = 0xffff;
+    gc3 = gdk_gc_new (widget->window);
+    gdk_gc_set_rgb_fg_color (gc3, &color);
+
+    for(i = 0; i < _gps.satinview; i++)
+    {
+        /* Sat used or not */
+        gc = gc1;
+        for(j = 0; j < _gps.satinuse ; j++)
+        {
+            if(_gps.satforfix[j] == _gps_sat[i].prn)
+            {
+                gc = gc2;
+                break;
+            }
+        }
+
+        tmp = deg2rad(_gps_sat[i].azimuth);
+        x = xoffset + halfsize
+            + (90 - _gps_sat[i].elevation)*halfsize/90 * sinf(tmp);
+        y = yoffset + halfsize
+            - (90 - _gps_sat[i].elevation)*halfsize/90 * cosf(tmp);
+
+        gdk_draw_arc (widget->window,
+            gc, TRUE,
+            x - 10, y - 10, 20, 20,
+            0, 64 * 360);
+
+        buffer = g_strdup_printf("%02d", _gps_sat[i].prn);
+        pango_layout_set_text(_sat_details_layout, buffer, -1);
+        pango_layout_get_pixel_size(_sat_details_layout, &x1, &y1);
+        gdk_draw_layout(widget->window,
+            gc3,
+            x - x1/2,
+            y - y1/2,
+            _sat_details_layout);
+        g_free(buffer);
+    }
+    g_object_unref (gc1);
+    g_object_unref (gc2);
+    g_object_unref (gc3);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+    return;
+}
+
+
+static gboolean
+sat_details_panel_expose(GtkWidget *widget, GdkEventExpose *event)
+{
+    gint width, height, x, y;
+    gchar *buffer = NULL;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    width = widget->allocation.width;
+    height = widget->allocation.height * 0.9;
+
+    draw_sat_info(widget, 0, 0, width/2, height, TRUE);
+    draw_sat_details(widget, width/2, 0, width/2, height);
+
+    buffer = g_strdup_printf(
+        "%s: %d; %s: %d",
+        _("Satellites in view"), _gps.satinview,
+        _("in use"), _gps.satinuse);
+    pango_layout_set_text(_sat_details_expose_layout, buffer, -1);
+    pango_layout_get_pixel_size(_sat_details_expose_layout, &x, &y);
+    gdk_draw_layout(widget->window,
+        widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+        10,
+        height*0.9 + 10,
+        _sat_details_expose_layout);
+    g_free(buffer);
+
+    buffer = g_strdup_printf("HDOP: %.01f", _gps.hdop);
+    pango_layout_set_text(_sat_details_expose_layout, buffer, -1);
+    pango_layout_get_pixel_size(_sat_details_expose_layout, &x, &y);
+    gdk_draw_layout(widget->window,
+        widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+        (width/8) - x/2,
+        (height/6) - y/2,
+        _sat_details_expose_layout);
+    g_free(buffer);
+    buffer = g_strdup_printf("PDOP: %.01f", _gps.pdop);
+    pango_layout_set_text(_sat_details_expose_layout, buffer, -1);
+    pango_layout_get_pixel_size(_sat_details_expose_layout, &x, &y);
+    gdk_draw_layout(widget->window,
+        widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+        (width/8) - x/2,
+        (height/6) - y/2 + 20,
+        _sat_details_expose_layout);
+    g_free(buffer);
+    buffer = g_strdup_printf("VDOP: %.01f", _gps.vdop);
+    pango_layout_set_text(_sat_details_expose_layout, buffer, -1);
+    pango_layout_get_pixel_size(_sat_details_expose_layout, &x, &y);
+    gdk_draw_layout(widget->window,
+        widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+        (width/8) - x/2,
+        (height/6) - y/2 + 40,
+        _sat_details_expose_layout);
+    g_free(buffer);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+void
+gps_details(void)
+{
+    static GtkWidget *dialog = NULL;
+    static GtkWidget *table = NULL;
+    static GtkWidget *label = NULL;
+    static GtkWidget *notebook = NULL;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(dialog == NULL)
+    {
+        dialog = gtk_dialog_new_with_buttons(_("GPS Details"),
+                GTK_WINDOW(_window), GTK_DIALOG_MODAL,
+                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+                NULL);
+
+        gtk_window_set_default_size(GTK_WINDOW(dialog), 600, 300);
+
+        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+                notebook = gtk_notebook_new(), TRUE, TRUE, 0);
+
+        /* textual info */
+        gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
+                table = gtk_table_new(4, 6, FALSE),
+                label = gtk_label_new(_("GPS Information")));
+
+        _sat_details_panel = gtk_drawing_area_new ();
+        gtk_widget_set_size_request (_sat_details_panel, 300, 300);
+        /* sat details info */
+        gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
+                _sat_details_panel,
+                label = gtk_label_new(_("Satellites details")));
+        g_signal_connect (G_OBJECT (_sat_details_panel), "expose_event",
+                            G_CALLBACK (sat_details_panel_expose), NULL);
+
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Latitude")),
+                0, 1, 0, 1, GTK_EXPAND | GTK_FILL, 0, 20, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                _sdi_lat = gtk_label_new(" --- "),
+                1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(_sdi_lat), 0.f, 0.5f);
+
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Longitude")),
+                0, 1, 1, 2, GTK_EXPAND | GTK_FILL, 0, 20, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                _sdi_lon = gtk_label_new(" --- "),
+                1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(_sdi_lon), 0.f, 0.5f);
+
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Speed")),
+                0, 1, 2, 3, GTK_EXPAND | GTK_FILL, 0, 20, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                _sdi_spd = gtk_label_new(" --- "),
+                1, 2, 2, 3, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(_sdi_spd), 0.f, 0.5f);
+
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Altitude")),
+                0, 1, 3, 4, GTK_EXPAND | GTK_FILL, 0, 20, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                _sdi_alt = gtk_label_new(" --- "),
+                1, 2, 3, 4, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(_sdi_alt), 0.f, 0.5f);
+
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Heading")),
+                0, 1, 4, 5, GTK_EXPAND | GTK_FILL, 0, 20, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                _sdi_hea = gtk_label_new(" --- "),
+                1, 2, 4, 5, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(_sdi_hea), 0.f, 0.5f);
+
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Local time")),
+                0, 1, 5, 6, GTK_EXPAND | GTK_FILL, 0, 20, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                _sdi_tim = gtk_label_new(" --:--:-- "),
+                1, 2, 5, 6, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(_sdi_tim), 0.f, 0.5f);
+
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Sat in view")),
+                2, 3, 0, 1, GTK_EXPAND | GTK_FILL, 0, 20, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                _sdi_vie = gtk_label_new("0"),
+                3, 4, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(_sdi_vie), 0.f, 0.5f);
+
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Sat in use")),
+                2, 3, 1, 2, GTK_EXPAND | GTK_FILL, 0, 20, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                _sdi_use = gtk_label_new("0"),
+                3, 4, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(_sdi_use), 0.f, 0.5f);
+
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Fix")),
+                2, 3, 2, 3, GTK_EXPAND | GTK_FILL, 0, 20, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                _sdi_fix = gtk_label_new(_("nofix")),
+                3, 4, 2, 3, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(_sdi_fix), 0.f, 0.5f);
+
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Fix Quality")),
+                2, 3, 3, 4, GTK_EXPAND | GTK_FILL, 0, 20, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                _sdi_fqu = gtk_label_new(_("none")),
+                3, 4, 3, 4, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(_sdi_fqu), 0.f, 0.5f);
+
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Max speed")),
+                2, 3, 5, 6, GTK_EXPAND | GTK_FILL, 0, 20, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                _sdi_msp = gtk_label_new(" --- "),
+                3, 4, 5, 6, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(_sdi_msp), 0.f, 0.5f);
+    }
+
+    gtk_widget_show_all(dialog);
+    _satdetails_on = TRUE;
+    gps_display_details();
+    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
+    {
+        _satdetails_on = FALSE;
+        break;
+    }
+    gtk_widget_hide(dialog);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+
+/**
+ * Render a single track line to _map_pixmap.  If either point on the line
+ * is a break (defined as unity == 0), a circle is drawn at the other point.
+ * IT IS AN ERROR FOR BOTH POINTS TO INDICATE A BREAK.
+ */
+void
+map_render_segment(GdkGC *gc_norm, GdkGC *gc_alt,
+        gint unitx1, gint unity1, gint unitx2, gint unity2)
+{
+    /* vprintf("%s(%d, %d, %d, %d)\n", __PRETTY_FUNCTION__,
+            unitx1, unity1, unitx2, unity2); */
+
+    if(!unity1)
+    {
+        gint x2, y2;
+        unit2buf(unitx2, unity2, x2, y2);
+        gdk_draw_arc(_map_pixmap, gc_alt,
+                FALSE, /* FALSE: not filled. */
+                x2 - _draw_width,
+                y2 - _draw_width,
+                2 * _draw_width,
+                2 * _draw_width,
+                0, /* start at 0 degrees. */
+                360 * 64);
+    }
+    else if(!unity2)
+    {
+        gint x1, y1;
+        unit2buf(unitx1, unity1, x1, y1);
+        gdk_draw_arc(_map_pixmap, gc_alt,
+                FALSE, /* FALSE: not filled. */
+                x1 - _draw_width,
+                y1 - _draw_width,
+                2 * _draw_width,
+                2 * _draw_width,
+                0, /* start at 0 degrees. */
+                360 * 64);
+    }
+    else
+    {
+        gint x1, y1, x2, y2;
+        unit2buf(unitx1, unity1, x1, y1);
+        unit2buf(unitx2, unity2, x2, y2);
+        gdk_draw_line(_map_pixmap, gc_norm, x1, y1, x2, y2);
+    }
+
+    /* vprintf("%s(): return\n", __PRETTY_FUNCTION__); */
+}
+
+/**
+ * Render all track data onto the _map_pixmap.  Note that this does not
+ * clear the pixmap of previous track data (use map_force_redraw() for
+ * that), and also note that this method does not queue any redraws, so it
+ * is up to the caller to decide which part of the track really needs to be
+ * redrawn.
+ */
+static void
+map_render_path(Path *path, GdkGC **gc)
+{
+    Point *curr;
+    WayPoint *wcurr;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    /* gc is a pointer to the first GC to use (for plain points).  (gc + 1)
+     * is a pointer to the GC to use for waypoints, and (gc + 2) is a pointer
+     * to the GC to use for breaks. */
+
+    /* else there is a route to draw. */
+    for(curr = path->head, wcurr = path->whead; curr++ != path->tail; )
+    {
+        /* Draw the line from (curr - 1) to (curr). */
+        map_render_segment(gc[0], gc[2],
+                curr[-1].unitx, curr[-1].unity, curr->unitx, curr->unity);
+
+        /* Now, check if curr is a waypoint. */
+        if(wcurr <= path->wtail && wcurr->point == curr)
+        {
+            gint x1, y1;
+            unit2buf(wcurr->point->unitx, wcurr->point->unity, x1, y1);
+            gdk_draw_arc(_map_pixmap,
+                    gc[1],
+                    FALSE, /* FALSE: not filled. */
+                    x1 - _draw_width,
+                    y1 - _draw_width,
+                    2 * _draw_width,
+                    2 * _draw_width,
+                    0, /* start at 0 degrees. */
+                    360 * 64);
+            wcurr++;
+        }
+    }
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+void
+map_render_paths()
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if((_show_paths & ROUTES_MASK) && _route.head != _route.tail)
+    {
+        WayPoint *next_way;
+        map_render_path(&_route, _gc + COLORABLE_ROUTE);
+
+        next_way = path_get_next_way();
+
+        /* Now, draw the next waypoint on top of all other waypoints. */
+        if(next_way)
+        {
+            gint x1, y1;
+            unit2buf(next_way->point->unitx, next_way->point->unity, x1, y1);
+            /* Draw the next waypoint as a break. */
+            gdk_draw_arc(_map_pixmap,
+                    _gc[COLORABLE_ROUTE_BREAK],
+                    FALSE, /* FALSE: not filled. */
+                    x1 - _draw_width,
+                    y1 - _draw_width,
+                    2 * _draw_width,
+                    2 * _draw_width,
+                    0, /* start at 0 degrees. */
+                    360 * 64);
+        }
+    }
+    if(_show_paths & TRACKS_MASK)
+        map_render_path(&_track, _gc + COLORABLE_TRACK);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+/**
+ * Update all GdkGC objects to reflect the current _draw_width.
+ */
+#define UPDATE_GC(gc) \
+    gdk_gc_set_line_attributes(gc, \
+            _draw_width, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
+void
+update_gcs()
+{
+    gint i;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    for(i = 0; i < COLORABLE_ENUM_COUNT; i++)
+    {
+        gdk_color_alloc(gtk_widget_get_colormap(_map_widget), &_color[i]);
+        if(_gc[i])
+            g_object_unref(_gc[i]);
+        _gc[i] = gdk_gc_new(_map_pixmap);
+        gdk_gc_set_foreground(_gc[i], &_color[i]);
+        gdk_gc_set_line_attributes(_gc[i],
+                _draw_width, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
+    }
+    
+    /* Update the _map_widget's gc's. */
+    gdk_gc_set_line_attributes(
+            _map_widget->style->fg_gc[GTK_STATE_ACTIVE],
+            2, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
+    gdk_gc_set_line_attributes(
+            _map_widget->style->bg_gc[GTK_STATE_ACTIVE],
+            2, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+/**
+ * Call gtk_window_present() on Maemo Mapper.  This also checks the
+ * configuration and brings up the Settings dialog if the GPS Receiver is
+ * not set up, the first time it is called.
+ */
+gboolean
+window_present()
+{
+    static gint been_here = 0;
+    static gint done_here = 0;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(!been_here++)
+    {
+        /* Set connection state first, to avoid going into this if twice. */
+        if(_gri.type == GPS_RCVR_NONE && _enable_gps)
+        {
+            GtkWidget *confirm;
+
+            gtk_window_present(GTK_WINDOW(_window));
+
+            confirm = hildon_note_new_confirmation(GTK_WINDOW(_window),
+                    _("It looks like this is your first time running"
+                        " Maemo Mapper.  Press OK to view the the help pages."
+                        " Otherwise, press Cancel to continue."));
+
+            if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm)))
+                ossohelp_show(_osso, HELP_ID_INTRO, 0);
+            gtk_widget_destroy(confirm);
+            if(settings_dialog())
+            {
+                popup_error(_window,
+                    _("OpenStreetMap.org provides public, free-to-use maps.  "
+                    "You can also download a sample set of repositories from "
+                    " the internet by using the \"Download...\" button."));
+                repoman_dialog();
+                if(_curr_repo->type != REPOTYPE_NONE)
+                {
+                    confirm = hildon_note_new_confirmation(GTK_WINDOW(_window),
+                        _("You will now see a blank screen.  You can download"
+                            " maps using the \"Manage Maps\" menu item in the"
+                            " \"Maps\" menu.  Or, press OK to enable"
+                            " Auto-Download."));
+                    if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm)))
+                    {
+                        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(
+                                    _menu_maps_auto_download_item), TRUE);
+                    }
+                    gtk_widget_destroy(confirm);
+                }
+            }
+            else
+                gtk_main_quit();
+        }
+
+        /* Connect to receiver. */
+        if(_enable_gps)
+            rcvr_connect();
+
+        ++done_here; /* Don't ask... */
+    }
+    if(done_here)
+    {
+        gtk_window_present(GTK_WINDOW(_window));
+        g_timeout_add(250, (GSourceFunc)banner_reset, NULL);
+    }
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+    return FALSE;
+}
+
+/**
+ * "Set" the mark, which translates the current GPS position into on-screen
+ * units in preparation for drawing the mark with map_draw_mark().
+ */
+static void
+map_set_mark()
+{
+    gfloat sqrt_speed, tmp, vel_offset_devx, vel_offset_devy;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    tmp = deg2rad(_gps.heading);
+    sqrt_speed = VELVEC_SIZE_FACTOR * sqrtf(10 + _gps.speed);
+    gdk_pixbuf_rotate_vector(&vel_offset_devx, &vel_offset_devy,
+            _map_rotate_matrix,
+            sqrt_speed * sinf(tmp), -sqrt_speed * cosf(tmp));
+
+    unit2buf(_pos.unitx, _pos.unity, _mark_bufx1, _mark_bufy1);
+
+    _mark_bufx2 = _mark_bufx1 + (_show_velvec ? (vel_offset_devx + 0.5f) : 0);
+    _mark_bufy2 = _mark_bufy1 + (_show_velvec ? (vel_offset_devy + 0.5f) : 0);
+
+    _mark_minx = MIN(_mark_bufx1, _mark_bufx2) - (2 * _draw_width);
+    _mark_miny = MIN(_mark_bufy1, _mark_bufy2) - (2 * _draw_width);
+    _mark_width = abs(_mark_bufx1 - _mark_bufx2) + (4 * _draw_width);
+    _mark_height = abs(_mark_bufy1 - _mark_bufy2) + (4 * _draw_width);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+
+/**
+ * Force a redraw of the entire _map_pixmap, including fetching the
+ * background maps from disk and redrawing the tracks on top of them.
+ */
+void
+map_force_redraw()
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    gdk_draw_pixbuf(
+            _map_pixmap,
+            _map_widget->style->fg_gc[GTK_STATE_ACTIVE],
+            _map_pixbuf,
+            0, 0,
+            0, 0,
+            _screen_width_pixels, _screen_height_pixels,
+            GDK_RGB_DITHER_NONE, 0, 0);
+
+    MACRO_MAP_RENDER_DATA();
+    MACRO_QUEUE_DRAW_AREA();
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+static Point
+map_calc_new_center(gint zoom)
+{
+    Point new_center;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    switch(_center_mode)
+    {
+        case CENTER_LEAD:
+        {
+            gfloat tmp = deg2rad(_gps.heading);
+            gfloat screen_pixels = _screen_width_pixels
+                + (((gint)_screen_height_pixels
+                            - (gint)_screen_width_pixels)
+                        * fabs(cosf(deg2rad(
+                                ROTATE_DIR_ENUM_DEGREES[_rotate_dir] -
+                                (_center_rotate ? 0
+                             : (_next_map_rotate_angle
+                                 - (gint)(_gps.heading)))))));
+            gfloat lead_pixels = 0.0025f
+                * pixel2zunit((gint)screen_pixels, zoom)
+                * _lead_ratio
+                * VELVEC_SIZE_FACTOR
+                * (_lead_is_fixed ? 7 : sqrtf(_gps.speed));
+
+            new_center.unitx = _pos.unitx + (gint)(lead_pixels * sinf(tmp));
+            new_center.unity = _pos.unity - (gint)(lead_pixels * cosf(tmp));
+            break;
+        }
+        case CENTER_LATLON:
+            new_center.unitx = _pos.unitx;
+            new_center.unity = _pos.unity;
+            break;
+        default:
+            new_center.unitx = _next_center.unitx;
+            new_center.unity = _next_center.unity;
+    }
+
+    vprintf("%s(): return (%d, %d)\n", __PRETTY_FUNCTION__,
+            new_center.unitx, new_center.unity);
+    return new_center;
+}
+
+/**
+ * Center the view on the given unitx/unity.
+ */
+void
+map_center_unit_full(Point new_center,
+        gint zoom, gint rotate_angle)
+{
+    MapRenderTask *mrt;
+    printf("%s(%d, %d)\n", __PRETTY_FUNCTION__,
+            new_center.unitx, new_center.unity);
+
+    if(!_mouse_is_down)
+    {
+        /* Assure that _center.unitx/y are bounded. */
+        BOUND(new_center.unitx,
+                pixel2unit(_screen_halfwidth_pixels),
+                WORLD_SIZE_UNITS - pixel2unit(_screen_halfwidth_pixels) - 1);
+        BOUND(new_center.unity,
+                pixel2unit(_screen_halfheight_pixels),
+                WORLD_SIZE_UNITS - pixel2unit(_screen_halfheight_pixels));
+
+        mrt = g_slice_new(MapRenderTask);
+        ++_redraw_count;
+        mrt->repo = _curr_repo;
+        mrt->old_offsetx = _map_offset_devx;
+        mrt->old_offsety = _map_offset_devy;
+        mrt->new_center = _next_center = new_center;
+        mrt->screen_width_pixels = _screen_width_pixels;
+        mrt->screen_height_pixels = _screen_height_pixels;
+        mrt->zoom = _next_zoom = zoom;
+        mrt->rotate_angle = _next_map_rotate_angle = rotate_angle;
+
+        gtk_widget_queue_draw_area(
+                _map_widget,
+                _redraw_wait_bounds.x,
+                _redraw_wait_bounds.y,
+                _redraw_wait_bounds.width + (_redraw_count - 1)
+                        * HOURGLASS_SEPARATION,
+                _redraw_wait_bounds.height);
+
+        g_thread_pool_push(_mrt_thread_pool, mrt, NULL);
+    }
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+void
+map_center_unit(Point new_center)
+{
+    map_center_unit_full(new_center, _next_zoom,
+        _center_mode > 0 && _center_rotate
+            ? _gps.heading : _next_map_rotate_angle);
+}
+
+void
+map_center_rotate(gint rotate_angle)
+{
+    map_center_unit_full(map_calc_new_center(_next_zoom), _next_zoom,
+        rotate_angle);
+}
+
+void
+map_center_zoom(gint zoom)
+{
+    map_center_unit_full(map_calc_new_center(zoom), zoom,
+        _center_mode > 0 && _center_rotate
+            ? _gps.heading : _next_map_rotate_angle);
+}
+
+/**
+ * Pan the view by the given number of units in the X and Y directions.
+ */
+void
+map_pan(gint delta_unitx, gint delta_unity)
+{
+    Point new_center;
+    printf("%s(%d, %d)\n", __PRETTY_FUNCTION__, delta_unitx, delta_unity);
+
+    if(_center_mode > 0)
+        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(
+                    _menu_view_ac_none_item), TRUE);
+    new_center.unitx = _center.unitx + delta_unitx;
+    new_center.unity = _center.unity + delta_unity;
+    map_center_unit_full(new_center, _next_zoom,
+            _center_mode > 0 && _center_rotate
+            ? _gps.heading : _next_map_rotate_angle);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+/**
+ * Initiate a move of the mark from the old location to the current
+ * location.  This function queues the draw area of the old mark (to force
+ * drawing of the background map), then updates the mark, then queus the
+ * draw area of the new mark.
+ */
+void
+map_move_mark()
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    /* Just queue the old and new draw areas. */
+    gtk_widget_queue_draw_area(_map_widget,
+            _mark_minx + _map_offset_devx,
+            _mark_miny + _map_offset_devy,
+            _mark_width,
+            _mark_height);
+    map_set_mark();
+    gtk_widget_queue_draw_area(_map_widget,
+            _mark_minx + _map_offset_devx,
+            _mark_miny + _map_offset_devy,
+            _mark_width,
+            _mark_height);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+/**
+ * Make sure the mark is up-to-date.  This function triggers a panning of
+ * the view if the mark is appropriately close to the edge of the view.
+ */
+void
+map_refresh_mark(gboolean force_redraw)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    gint new_center_devx, new_center_devy;
+
+    Point new_center = map_calc_new_center(_next_zoom);
+
+    unit2buf(new_center.unitx, new_center.unity,
+            new_center_devx, new_center_devy);
+    if(force_redraw || (_center_mode > 0 && _gps.speed > 0 &&
+    (((unsigned)(new_center_devx - (_screen_width_pixels * _center_ratio / 20))
+                > ((10 - _center_ratio) * _screen_width_pixels / 10))
+ || ((unsigned)(new_center_devy - (_screen_height_pixels * _center_ratio / 20))
+                > ((10 - _center_ratio) * _screen_height_pixels / 10))
+            || (_center_rotate &&
+              abs(_next_map_rotate_angle - _gps.heading)
+                  > (4*(10-_rotate_sens))))))
+    {
+        map_move_mark();
+        map_center_unit(new_center);
+    }
+    else
+    {
+        /* We're not changing the view - just move the mark. */
+        map_move_mark();
+    }
+
+    /* Draw speed info */
+    if(_speed_limit_on)
+        speed_limit();
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+gboolean
+map_download_refresh_idle(MapUpdateTask *mut)
+{
+    vprintf("%s(%p, %d, %d, %d)\n", __PRETTY_FUNCTION__, mut,
+            mut->zoom, mut->tilex, mut->tiley);
+
+    /* Test if download succeeded (only if retries != 0). */
+    if(mut->pixbuf && mut->repo == _curr_repo)
+    {
+        gint zoff = mut->zoom - _zoom;
+        /* Update the UI to reflect the updated map database. */
+        /* Only refresh at same or "lower" (more detailed) zoom level. */
+        if(mut->update_type == MAP_UPDATE_AUTO && (unsigned)zoff <= 4)
+        {
+            gfloat destx, desty;
+            gint boundx, boundy, width, height;
+
+            pixel2buf(
+                    tile2pixel(mut->tilex << zoff)
+                        + ((TILE_SIZE_PIXELS << zoff) >> 1),
+                    tile2pixel(mut->tiley << zoff)
+                        + ((TILE_SIZE_PIXELS << zoff) >> 1),
+                    destx, desty);
+
+            /* Multiply the matrix to cause blitting. */
+            if(zoff)
+                gdk_pixbuf_rotate_matrix_mult_number(
+                        _map_rotate_matrix, 1 << zoff);
+            gdk_pixbuf_rotate(_map_pixbuf,
+                        destx, desty,
+                        _map_rotate_matrix,
+                        mut->pixbuf,
+                        TILE_SIZE_PIXELS / 2,
+                        TILE_SIZE_PIXELS / 2,
+                        TILE_SIZE_PIXELS,
+                        TILE_SIZE_PIXELS,
+                        &boundx, &boundy, &width, &height);
+            /* Un-multiply the matrix that we used for blitting. */
+            if(zoff)
+                gdk_pixbuf_rotate_matrix_mult_number(
+                        _map_rotate_matrix, 1.f / (1 << zoff));
+
+            if(width * height)
+            {
+                gdk_draw_pixbuf(
+                        _map_pixmap,
+                        _map_widget->style->fg_gc[GTK_STATE_ACTIVE],
+                        _map_pixbuf,
+                        boundx, boundy,
+                        boundx, boundy,
+                        width, height,
+                        GDK_RGB_DITHER_NONE, 0, 0);
+                MACRO_MAP_RENDER_DATA();
+                gtk_widget_queue_draw_area(
+                    _map_widget, boundx, boundy, width, height);
+            }
+        }
+        g_object_unref(mut->pixbuf);
+    }
+    else if(mut->vfs_result != GNOME_VFS_OK)
+    {
+        _dl_errors++;
+    }
+
+    if(++_curr_download == _num_downloads)
+    {
+        gtk_widget_destroy(_download_banner);
+        _download_banner = NULL;
+        _num_downloads = _curr_download = 0;
+        g_thread_pool_stop_unused_threads();
+#ifndef MAPDB_SQLITE
+        if(_curr_repo->db)
+            gdbm_sync(_curr_repo->db);
+#endif
+        if(_dl_errors)
+        {
+            gchar buffer[BUFFER_SIZE];
+            snprintf(buffer, sizeof(buffer), "%d %s", _dl_errors,
+                    _("maps failed to download."));
+            MACRO_BANNER_SHOW_INFO(_window, buffer);
+            _dl_errors = 0;
+        }
+        else if(mut->update_type != MAP_UPDATE_AUTO)
+        {
+            /* Update the map. */
+            map_refresh_mark(TRUE);
+        }
+    }
+    else if(_download_banner)
+    {
+        hildon_banner_set_fraction(HILDON_BANNER(_download_banner),
+                _curr_download / (double)_num_downloads);
+    }
+
+    g_mutex_lock(_mut_priority_mutex);
+    g_hash_table_remove(_mut_exists_table, mut);
+    g_mutex_unlock(_mut_priority_mutex);
+
+    g_slice_free(MapUpdateTask, mut);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+    return FALSE;
+}
+
+/**
+ * Set the current zoom level.  If the given zoom level is the same as the
+ * current zoom level, or if the new zoom is invalid
+ * (not MIN_ZOOM <= new_zoom < MAX_ZOOM), then this method does nothing.
+ */
+void
+map_set_zoom(gint new_zoom)
+{
+    printf("%s(%d)\n", __PRETTY_FUNCTION__, _zoom);
+
+    /* Note that, since new_zoom is a gint and MIN_ZOOM is 0, this if
+     * condition also checks for new_zoom >= MIN_ZOOM. */
+    if(new_zoom > (MAX_ZOOM - 1))
+        return;
+
+    map_center_zoom(new_zoom / _curr_repo->view_zoom_steps
+                     * _curr_repo->view_zoom_steps);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+static gboolean
+map_replace_pixbuf_idle(MapRenderTask *mrt)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(!_mouse_is_down
+            && mrt->screen_width_pixels == _screen_width_pixels
+            && mrt->screen_height_pixels == _screen_height_pixels)
+    {
+        g_object_unref(_map_pixbuf);
+        _map_pixbuf = mrt->pixbuf;
+        _center = mrt->new_center;
+        _zoom = mrt->zoom;
+
+        _map_rotate_angle = mrt->rotate_angle;
+        gdk_pixbuf_rotate_matrix_fill_for_rotation(
+                _map_rotate_matrix,
+                deg2rad(ROTATE_DIR_ENUM_DEGREES[_rotate_dir]
+                    - _map_rotate_angle));
+        gdk_pixbuf_rotate_matrix_fill_for_rotation(
+                _map_reverse_matrix,
+                deg2rad(_map_rotate_angle
+                    - ROTATE_DIR_ENUM_DEGREES[_rotate_dir]));
+
+        g_slice_free(MapRenderTask, mrt);
+        --_redraw_count;
+
+        _map_offset_devx = 0;
+        _map_offset_devy = 0;
+
+        map_set_mark();
+        map_force_redraw();
+    }
+    else
+    {
+        /* Ignore this new pixbuf. We have newer ones coming. */
+        g_object_unref(mrt->pixbuf);
+        g_slice_free(MapRenderTask, mrt);
+        gtk_widget_queue_draw_area(
+                _map_widget,
+                _redraw_wait_bounds.x,
+                _redraw_wait_bounds.y,
+                _redraw_wait_bounds.width + (_redraw_count - 1)
+                        * HOURGLASS_SEPARATION,
+                _redraw_wait_bounds.height * _redraw_count);
+        --_redraw_count;
+    }
+
+    vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+    return FALSE;
+}
+
+gboolean
+thread_render_map(MapRenderTask *mrt)
+{
+    gfloat matrix[4];
+    gint start_tilex, start_tiley, stop_tilex, stop_tiley;
+    gint x = 0, y, num_tilex, num_tiley;
+    gint diag_halflength_units;
+    gfloat angle_rad;
+    gint tile_rothalf_pixels;
+    gint curr_tile_to_draw, num_tiles_to_draw;
+    gfloat *tile_dev;
+    ThreadLatch *refresh_latch = NULL;
+    gint cache_amount;
+    static gint auto_download_batch_id = 0;
+    printf("%s(%d, %d, %d, %d, %d, %d)\n", __PRETTY_FUNCTION__,
+            mrt->screen_width_pixels, mrt->screen_height_pixels,
+            mrt->new_center.unitx, mrt->new_center.unity, mrt->zoom,
+            mrt->rotate_angle);
+
+    /* If there are more render tasks in the queue, skip this one. */
+    if(g_thread_pool_unprocessed(_mrt_thread_pool))
+    {
+        g_slice_free(MapRenderTask, mrt);
+        gtk_widget_queue_draw_area(
+                _map_widget,
+                _redraw_wait_bounds.x,
+                _redraw_wait_bounds.y,
+                _redraw_wait_bounds.width + (_redraw_count - 1)
+                        * HOURGLASS_SEPARATION,
+                _redraw_wait_bounds.height * _redraw_count);
+        --_redraw_count;
+        vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+        return FALSE;
+    }
+
+    angle_rad = deg2rad(ROTATE_DIR_ENUM_DEGREES[_rotate_dir]
+            - mrt->rotate_angle);
+
+    gdk_pixbuf_rotate_matrix_fill_for_rotation(matrix, angle_rad);
+
+    /* Determine (roughly) the tiles we might have to process.
+     * Basically, we take the center unit and subtract the maximum dimension
+     * of the screen plus the maximum additional pixels of a rotated tile.
+     */
+    tile_rothalf_pixels = MAX(
+            fabs(TILE_HALFDIAG_PIXELS * sinf((PI / 4) - angle_rad)),
+            fabs(TILE_HALFDIAG_PIXELS * cosf((PI / 4) - angle_rad)));
+
+    mrt->zoom = _next_zoom;
+
+    if(mrt->repo->type != REPOTYPE_NONE && mrt->repo->db)
+        cache_amount = _auto_download_precache;
+    else
+        cache_amount = 1; /* No cache. */
+
+    diag_halflength_units = pixel2zunit(TILE_HALFDIAG_PIXELS
+        + MAX(mrt->screen_width_pixels, mrt->screen_height_pixels) / 2,
+        mrt->zoom);
+    start_tilex = unit2ztile(
+            mrt->new_center.unitx - diag_halflength_units, mrt->zoom);
+    start_tilex = MAX(start_tilex - (cache_amount - 1), 0);
+    start_tiley = unit2ztile(
+            mrt->new_center.unity - diag_halflength_units, mrt->zoom);
+    start_tiley = MAX(start_tiley - (cache_amount - 1), 0);
+    stop_tilex = unit2ztile(mrt->new_center.unitx + diag_halflength_units,
+            mrt->zoom);
+    stop_tilex = MIN(stop_tilex + (cache_amount - 1),
+            unit2ztile(WORLD_SIZE_UNITS, mrt->zoom));
+    stop_tiley = unit2ztile(mrt->new_center.unity + diag_halflength_units,
+            mrt->zoom);
+    stop_tiley = MIN(stop_tiley + (cache_amount - 1),
+            unit2ztile(WORLD_SIZE_UNITS, mrt->zoom));
+
+    num_tilex = (stop_tilex - start_tilex + 1);
+    num_tiley = (stop_tiley - start_tiley + 1);
+    tile_dev = g_new0(gfloat, num_tilex * num_tiley * 2);
+
+    ++auto_download_batch_id;
+
+    /* Iterate through the tiles and mark which ones need retrieval. */
+    num_tiles_to_draw = 0;
+    for(y = 0; y < num_tiley; ++y)
+    {
+        for(x = 0; x < num_tilex; ++x)
+        {
+            gfloat devx, devy;
+
+            /* Find the device location of this tile's center. */
+            pixel2buf_full(
+                    tile2pixel(x + start_tilex) + (TILE_SIZE_PIXELS >> 1),
+                    tile2pixel(y + start_tiley) + (TILE_SIZE_PIXELS >> 1),
+                    devx, devy,
+                    mrt->new_center, mrt->zoom, matrix);
+
+            /* Skip this tile under the following conditions:
+             * devx < -tile_rothalf_pixels
+             * devx > _screen_width_pixels + tile_rothalf_pixels
+             * devy < -tile_rothalf_pixels
+             * devy > _screen_height_pixels + tile_rothalf_pixels
+             */
+            if(((unsigned)(devx + tile_rothalf_pixels))
+                    < (_screen_width_pixels + (2 * tile_rothalf_pixels))
+                && ((unsigned)(devy + tile_rothalf_pixels))
+                    < (_screen_height_pixels + (2 * tile_rothalf_pixels)))
+            {
+                tile_dev[2 * (y * num_tilex + x)] = devx;
+                tile_dev[2 * (y * num_tilex + x) + 1] = devy;
+                ++num_tiles_to_draw;
+            }
+            else
+            {
+                tile_dev[2 * (y * num_tilex + x)] = FLT_MAX;
+            }
+        }
+    }
+
+    mrt->pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8,
+            mrt->screen_width_pixels, mrt->screen_height_pixels);
+
+    /* Iterate through the tiles, get them (or queue a download if they're
+     * not in the cache), and rotate them into the pixbuf. */
+    for(y = curr_tile_to_draw = 0; y < num_tiley; ++y)
+    {
+        gint tiley = y + start_tiley;
+        for(x = 0; x < num_tilex; ++x)
+        {
+            GdkPixbuf *tile_pixbuf = NULL;
+            gboolean started_download = FALSE;
+            gint zoff;
+            gint tilex;
+
+            tilex = x + start_tilex;
+
+            zoff = mrt->repo->double_size ? 1 : 0;
+
+            /* Iteratively try to retrieve a map to draw the tile. */
+            while((mrt->zoom + zoff) <= MAX_ZOOM && zoff < TILE_SIZE_P2)
+            {
+                /* Check if we're actually going to draw this map. */
+                if(tile_dev[2 * (y*num_tilex + x)] != FLT_MAX)
+                {
+                    if(NULL != (tile_pixbuf = mapdb_get(
+                                    mrt->repo, mrt->zoom + zoff,
+                                    tilex >> zoff,
+                                    tiley >> zoff)))
+                    {
+                        /* Found a map. */
+                        break;
+                    }
+                }
+                /* Else we're not going to be drawing this map, so just check
+                 * if it's in the database. */
+                else if(mapdb_exists(
+                                    mrt->repo, mrt->zoom + zoff,
+                                    tilex >> zoff,
+                                    tiley >> zoff, FALSE))
+                {
+                    break;
+                }
+
+                /* No map; download, if we should. */
+                if(!started_download && _auto_download
+                        && mrt->repo->type != REPOTYPE_NONE
+                        /* Make sure this map matches the dl_zoom_steps,
+                         * or that there currently is no cache. */
+                        && (!mrt->repo->db || !((mrt->zoom + zoff
+                                    - (mrt->repo->double_size ? 1 : 0))
+                                % mrt->repo->dl_zoom_steps))
+                    /* Make sure this tile is even possible. */
+                    && ((unsigned)tilex < unit2ztile(WORLD_SIZE_UNITS,
+                            mrt->zoom + zoff)
+                      && (unsigned)tiley < unit2ztile(WORLD_SIZE_UNITS,
+                          mrt->zoom + zoff)))
+                {
+                    started_download = TRUE;
+
+                    if(!refresh_latch)
+                    {
+                        refresh_latch = g_slice_new(ThreadLatch);
+                        refresh_latch->is_open = FALSE;
+                        refresh_latch->is_done_adding_tasks = FALSE;
+                        refresh_latch->num_tasks = 1;
+                        refresh_latch->num_done = 0;
+                        refresh_latch->mutex = g_mutex_new();
+                        refresh_latch->cond = g_cond_new();
+                    }
+                    else
+                        ++refresh_latch->num_tasks;
+
+                    mapdb_initiate_update(
+                            mrt->repo,
+                            mrt->zoom + zoff,
+                            tilex >> zoff,
+                            tiley >> zoff,
+                            MAP_UPDATE_AUTO,
+                            auto_download_batch_id,
+                            (abs((tilex >> zoff) - unit2ztile(
+                                     mrt->new_center.unitx, mrt->zoom + zoff))
+                             + abs((tiley >> zoff) - unit2ztile(
+                                    mrt->new_center.unity, mrt->zoom + zoff))),
+                            refresh_latch);
+                }
+
+                /* Try again at a coarser resolution. */
+                ++zoff;
+            }
+
+            if(tile_pixbuf)
+            {
+                gint boundx, boundy, width, height;
+                if(zoff)
+                    gdk_pixbuf_rotate_matrix_mult_number(matrix, 1 << zoff);
+                gdk_pixbuf_rotate(mrt->pixbuf,
+                        tile_dev[2 * (y * num_tilex + x)],
+                        tile_dev[2 * (y * num_tilex + x) + 1],
+                        matrix,
+                        tile_pixbuf,
+                        ((tilex - ((tilex >> zoff) << zoff))
+                            << (TILE_SIZE_P2 - zoff))
+                            + (TILE_SIZE_PIXELS >> (1 + zoff)),
+                        ((tiley - ((tiley>>zoff) << zoff))
+                            << (TILE_SIZE_P2 - zoff))
+                            + (TILE_SIZE_PIXELS >> (1 + zoff)),
+                        TILE_SIZE_PIXELS >> zoff,
+                        TILE_SIZE_PIXELS >> zoff,
+                        &boundx, &boundy, &width, &height);
+                g_object_unref(tile_pixbuf);
+                /* Un-multiply the matrix that we used for blitting. */
+                if(zoff)
+                    gdk_pixbuf_rotate_matrix_mult_number(
+                            matrix, 1.f / (1 << zoff));
+            }
+            /* usleep(10000); DEBUG */
+        }
+    }
+
+    /* Don't replace the pixbuf unless/until the mouse is released. */
+    g_mutex_lock(_mouse_mutex);
+    g_idle_add_full(G_PRIORITY_HIGH_IDLE,
+            (GSourceFunc)map_replace_pixbuf_idle, mrt, NULL);
+    g_mutex_unlock(_mouse_mutex);
+
+    /* Release the view-change lock. */
+    if(refresh_latch)
+    {
+        g_mutex_lock(refresh_latch->mutex);
+        if(refresh_latch->num_tasks == refresh_latch->num_done)
+        {
+            /* Fast little workers, aren't they? */
+            g_mutex_unlock(refresh_latch->mutex);
+            g_cond_free(refresh_latch->cond);
+            g_mutex_free(refresh_latch->mutex);
+            g_slice_free(ThreadLatch, refresh_latch);
+        }
+        else
+        {
+            refresh_latch->is_done_adding_tasks = TRUE;
+            refresh_latch->is_open = TRUE;
+            g_cond_signal(refresh_latch->cond);
+            g_mutex_unlock(refresh_latch->mutex);
+        }
+    }
+
+    g_free(tile_dev);
+
+    vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+    return FALSE;
+}
+
+gboolean
+map_cb_configure(GtkWidget *widget, GdkEventConfigure *event)
+{
+    gint old_screen_width_pixels, old_screen_height_pixels;
+    GdkPixbuf *old_map_pixbuf;
+    printf("%s(%d, %d)\n", __PRETTY_FUNCTION__,
+            _map_widget->allocation.width, _map_widget->allocation.height);
+
+    if(_map_widget->allocation.width == 1
+            && _map_widget->allocation.height == 1)
+        /* Special case - first allocation - not persistent. */
+        return TRUE;
+
+    old_screen_width_pixels = _screen_width_pixels;
+    old_screen_height_pixels = _screen_height_pixels;
+    _screen_width_pixels = _map_widget->allocation.width;
+    _screen_height_pixels = _map_widget->allocation.height;
+    _screen_halfwidth_pixels = _screen_width_pixels / 2;
+    _screen_halfheight_pixels = _screen_height_pixels / 2;
+
+    g_object_unref(_map_pixmap);
+    _map_pixmap = gdk_pixmap_new(
+                _map_widget->window,
+                _screen_width_pixels, _screen_height_pixels,
+                -1); /* -1: use bit depth of widget->window. */
+
+    old_map_pixbuf = _map_pixbuf;
+    _map_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8,
+            _screen_width_pixels, _screen_height_pixels);
+
+    {
+        gint oldnew_diffx = (gint)(_screen_width_pixels
+                - old_screen_width_pixels) / 2;
+        gint oldnew_diffy = (gint)(_screen_height_pixels
+                - old_screen_height_pixels) / 2;
+        gdk_pixbuf_copy_area(old_map_pixbuf,
+                MAX(0, -oldnew_diffx), MAX(0, -oldnew_diffy),
+                MIN(_screen_width_pixels, old_screen_width_pixels),
+                MIN(_screen_height_pixels, old_screen_height_pixels),
+                _map_pixbuf,
+                MAX(0, oldnew_diffx), MAX(0, oldnew_diffy));
+    }
+
+    g_object_unref(old_map_pixbuf);
+
+    /* Set _scale_rect. */
+    _scale_rect.x = (_screen_width_pixels - SCALE_WIDTH) / 2;
+    _scale_rect.width = SCALE_WIDTH;
+    pango_layout_set_text(_scale_layout, "0", -1);
+    pango_layout_get_pixel_size(_scale_layout, NULL, &_scale_rect.height);
+    _scale_rect.y = _screen_height_pixels - _scale_rect.height - 1;
+
+    /* Set _zoom rect. */
+    pango_layout_set_text(_zoom_layout, "00", -1);
+    pango_layout_get_pixel_size(_zoom_layout, &_zoom_rect.width,
+            &_zoom_rect.height);
+    _zoom_rect.width *= 1.25;
+    pango_layout_set_width(_zoom_layout, _zoom_rect.width);
+    pango_layout_context_changed(_zoom_layout);
+    _zoom_rect.x = _scale_rect.x - _zoom_rect.width;
+    _zoom_rect.y = _screen_height_pixels - _zoom_rect.height - 1;
+
+    /* Set _comprose_rect. */
+    _comprose_rect.x = _screen_width_pixels - 25 - _comprose_rect.width;
+    _comprose_rect.y = _screen_height_pixels - 25 - _comprose_rect.height;
+
+    map_set_mark();
+    map_force_redraw();
+
+    /* If Auto-Center is set to Lead, then recalc center. */
+    if(_center_mode == CENTER_LEAD)
+        map_center_unit(map_calc_new_center(_next_zoom));
+    else
+        map_center_unit(_next_center);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+gboolean
+sat_panel_expose(GtkWidget *widget, GdkEventExpose *event)
+{
+    gchar *tmp = NULL;
+    gint x, y;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    draw_sat_info(widget,
+        0, 0,
+        widget->allocation.width,
+        widget->allocation.height,
+        FALSE);
+
+    /* Sat View/In Use */
+    tmp = g_strdup_printf("%d/%d", _gps.satinuse, _gps.satinview);
+    pango_layout_set_text(_sat_panel_layout, tmp, -1);
+    pango_layout_set_alignment(_sat_panel_layout, PANGO_ALIGN_LEFT);
+    gdk_draw_layout(widget->window,
+        widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+        20, 2,
+        _sat_panel_layout);
+    g_free(tmp);
+
+    switch(_gps.fix)
+    {
+        case 2:
+        case 3: tmp = g_strdup_printf("%dD fix", _gps.fix); break;
+        default: tmp = g_strdup_printf("nofix"); break;
+    }
+    pango_layout_set_text(_sat_panel_layout, tmp, -1);
+    pango_layout_set_alignment(_sat_panel_layout, PANGO_ALIGN_RIGHT);
+    pango_layout_get_pixel_size(_sat_panel_layout, &x, &y);
+    gdk_draw_layout(widget->window,
+        widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+        widget->allocation.width - 20 - x, 2,
+        _sat_panel_layout);
+    g_free(tmp);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+gboolean
+heading_panel_expose(GtkWidget *widget, GdkEventExpose *event)
+{
+    gint size, xoffset, yoffset, i, x, y;
+    gint dir;
+    gfloat tmp;
+    gchar *text;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    size = MIN(widget->allocation.width, widget->allocation.height);
+    if(widget->allocation.width > widget->allocation.height)
+    {
+        xoffset = (widget->allocation.width - widget->allocation.height) / 2;
+        yoffset = 0;
+    }
+    else
+    {
+        xoffset = 0;
+        yoffset = (widget->allocation.height - widget->allocation.width) / 2;
+    }
+    pango_font_description_set_size(_heading_panel_fontdesc,12*PANGO_SCALE);
+    pango_layout_set_font_description(_heading_panel_layout,
+            _heading_panel_fontdesc);
+    pango_layout_set_alignment(_heading_panel_layout, PANGO_ALIGN_CENTER);
+
+    text = g_strdup_printf("%3.0f°", _gps.heading);
+    pango_layout_set_text(_heading_panel_layout, text, -1);
+    pango_layout_get_pixel_size(_heading_panel_layout, &x, &y);
+
+    gdk_draw_layout(widget->window,
+        widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+        xoffset + size/2 - x/2,
+        yoffset + size - y - 2, _heading_panel_layout);
+    g_free(text);
+
+    gdk_draw_arc (widget->window,
+        widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+        FALSE,
+        xoffset, yoffset + size/2,
+        size, size,
+        0, 64 * 180);
+
+    /* Simple arrow for heading*/
+    gdk_draw_line(widget->window,
+        widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+        xoffset + size/2 + 3,
+        yoffset + size - y - 5,
+        xoffset + size/2,
+        yoffset + size/2 + 5);
+
+    gdk_draw_line(widget->window,
+        widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+        xoffset + size/2 - 3,
+        yoffset + size - y - 5,
+        xoffset + size/2,
+        yoffset + size/2 + 5);
+
+    gdk_draw_line(widget->window,
+        widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+        xoffset + size/2 - 3,
+        yoffset + size - y - 5,
+        xoffset + size/2,
+        yoffset + size - y - 8);
+
+    gdk_draw_line(widget->window,
+        widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+        xoffset + size/2 + 3,
+        yoffset + size - y - 5,
+        xoffset + size/2,
+        yoffset + size - y - 8);
+
+    gint angle[5] = {-90,-45,0,45,90};
+    gint fsize[5] = {0,4,10,4,0};
+    for(i = 0; i < 5; i++)
+    {
+        dir = (gint)(_gps.heading/45)*45 + angle[i];
+
+        switch(dir)
+        {
+            case   0:
+            case 360: text = g_strdup("N"); break;
+            case  45:
+            case 405:
+                text = g_strdup("NE"); break;
+            case  90:
+                text = g_strdup("E"); break;
+            case 135:
+                text = g_strdup("SE"); break;
+            case 180:
+                text = g_strdup("S"); break;
+            case 225:
+                text = g_strdup("SW"); break;
+            case 270:
+            case -90:
+                text = g_strdup("W"); break;
+            case 315:
+            case -45:
+                text = g_strdup("NW"); break;
+            default :
+                text = g_strdup("??");
+                break;
+        }
+
+        tmp = deg2rad(dir - _gps.heading);
+        gdk_draw_line(widget->window,
+            widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+            xoffset + size/2 + ((size/2 - 5) * sinf(tmp)),
+            yoffset + size - ((size/2 - 5) * cosf(tmp)),
+            xoffset + size/2 + ((size/2 + 5) * sinf(tmp)),
+            yoffset + size - ((size/2 + 5) * cosf(tmp)));
+
+        x = fsize[i];
+        if(abs((gint)(_gps.heading/45)*45 - _gps.heading)
+                > abs((gint)(_gps.heading/45)*45 + 45 - _gps.heading)
+                && (i > 0))
+            x = fsize[i - 1];
+
+        pango_font_description_set_size(_heading_panel_fontdesc,
+                (10 + x)*PANGO_SCALE);
+        pango_layout_set_font_description(_heading_panel_layout,
+                _heading_panel_fontdesc);
+        pango_layout_set_text(_heading_panel_layout, text, -1);
+        pango_layout_get_pixel_size(_heading_panel_layout, &x, &y);
+        x = xoffset + size/2 + ((size/2 + 15) * sinf(tmp)) - x/2,
+        y = yoffset + size - ((size/2 + 15) * cosf(tmp)) - y/2,
+
+        gdk_draw_layout(widget->window,
+            widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+            x, y, _heading_panel_layout);
+        g_free(text);
+    }
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+gboolean
+map_cb_expose(GtkWidget *widget, GdkEventExpose *event)
+{
+    gint i;
+    printf("%s(%d, %d, %d, %d)\n", __PRETTY_FUNCTION__,
+            event->area.x, event->area.y,
+            event->area.width, event->area.height);
+
+    /* Perform rotation. */
+    gdk_draw_drawable(
+            _map_widget->window,
+            _gc[COLORABLE_MARK],
+            _map_pixmap,
+            event->area.x - _map_offset_devx, event->area.y - _map_offset_devy,
+            event->area.x, event->area.y,
+            event->area.width, event->area.height);
+
+    /* Draw the mark. */
+    gdk_draw_arc(
+            _map_widget->window,
+            _gps_state == RCVR_FIXED
+                ? _gc[COLORABLE_MARK] : _gc[COLORABLE_MARK_OLD],
+            FALSE, /* not filled. */
+            _mark_bufx1 - _draw_width + _map_offset_devx,
+            _mark_bufy1 - _draw_width + _map_offset_devy,
+            2 * _draw_width, 2 * _draw_width,
+            0, 360 * 64);
+    gdk_draw_line(
+            _map_widget->window,
+            _gps_state == RCVR_FIXED
+                ? (_show_velvec
+                    ? _gc[COLORABLE_MARK_VELOCITY] : _gc[COLORABLE_MARK])
+                : _gc[COLORABLE_MARK_OLD],
+            _mark_bufx1 + _map_offset_devx,
+            _mark_bufy1 + _map_offset_devy,
+            _mark_bufx2 + _map_offset_devx,
+            _mark_bufy2 + _map_offset_devy);
+
+    /* draw zoom box if so wanted */
+    if(_show_zoomlevel) {
+        gchar *buffer = g_strdup_printf("%d", _zoom);
+        gdk_draw_rectangle(_map_widget->window,
+                _map_widget->style->bg_gc[GTK_STATE_ACTIVE],
+                TRUE,
+                _zoom_rect.x, _zoom_rect.y,
+                _zoom_rect.width, _zoom_rect.height);
+        gdk_draw_rectangle(_map_widget->window,
+                _map_widget->style->fg_gc[GTK_STATE_ACTIVE],
+                FALSE,
+                _zoom_rect.x, _zoom_rect.y,
+                _zoom_rect.width, _zoom_rect.height);
+        pango_layout_set_text(_zoom_layout, buffer, -1);
+        gdk_draw_layout(_map_widget->window,
+                _map_widget->style->fg_gc[GTK_STATE_ACTIVE],
+                _zoom_rect.x + _zoom_rect.width / 2,
+                _zoom_rect.y, _zoom_layout);
+    }
+
+    /* Draw scale, if necessary. */
+    if(_show_scale)
+    {
+        gdk_rectangle_intersect(&event->area, &_scale_rect, &event->area);
+        if(event->area.width && event->area.height)
+        {
+            gdk_draw_rectangle(_map_widget->window,
+                    _map_widget->style->bg_gc[GTK_STATE_ACTIVE],
+                    TRUE,
+                    _scale_rect.x, _scale_rect.y,
+                    _scale_rect.width, _scale_rect.height);
+            gdk_draw_rectangle(_map_widget->window,
+                    _map_widget->style->fg_gc[GTK_STATE_ACTIVE],
+                    FALSE,
+                    _scale_rect.x, _scale_rect.y,
+                    _scale_rect.width, _scale_rect.height);
+
+            /* Now calculate and draw the distance. */
+            {
+                gchar buffer[16];
+                gfloat distance;
+                gfloat lat1, lon1, lat2, lon2;
+                gint width;
+
+                unit2latlon(_center.unitx - pixel2unit(SCALE_WIDTH / 2 - 4),
+                        _center.unity, lat1, lon1);
+                unit2latlon(_center.unitx + pixel2unit(SCALE_WIDTH / 2 - 4),
+                        _center.unity, lat2, lon2);
+                distance = calculate_distance(lat1, lon1, lat2, lon2)
+                    * UNITS_CONVERT[_units];
+
+                if(distance < 1.f)
+                    snprintf(buffer, sizeof(buffer), "%0.2f %s", distance,
+                            UNITS_ENUM_TEXT[_units]);
+                else if(distance < 10.f)
+                    snprintf(buffer, sizeof(buffer), "%0.1f %s", distance,
+                            UNITS_ENUM_TEXT[_units]);
+                else
+                    snprintf(buffer, sizeof(buffer), "%0.f %s", distance,
+                            UNITS_ENUM_TEXT[_units]);
+                pango_layout_set_text(_scale_layout, buffer, -1);
+
+                pango_layout_get_pixel_size(_scale_layout, &width, NULL);
+
+                /* Draw the layout itself. */
+                gdk_draw_layout(_map_widget->window,
+                    _map_widget->style->fg_gc[GTK_STATE_ACTIVE],
+                    _scale_rect.x + (_scale_rect.width - width) / 2,
+                    _scale_rect.y, _scale_layout);
+
+                /* Draw little hashes on the ends. */
+                gdk_draw_line(_map_widget->window,
+                    _map_widget->style->fg_gc[GTK_STATE_ACTIVE],
+                    _scale_rect.x + 4,
+                    _scale_rect.y + _scale_rect.height / 2 - 4,
+                    _scale_rect.x + 4,
+                    _scale_rect.y + _scale_rect.height / 2 + 4);
+                gdk_draw_line(_map_widget->window,
+                    _map_widget->style->fg_gc[GTK_STATE_ACTIVE],
+                    _scale_rect.x + 4,
+                    _scale_rect.y + _scale_rect.height / 2,
+                    _scale_rect.x + (_scale_rect.width - width) / 2 - 4,
+                    _scale_rect.y + _scale_rect.height / 2);
+                gdk_draw_line(_map_widget->window,
+                    _map_widget->style->fg_gc[GTK_STATE_ACTIVE],
+                    _scale_rect.x + _scale_rect.width - 4,
+                    _scale_rect.y + _scale_rect.height / 2 - 4,
+                    _scale_rect.x + _scale_rect.width - 4,
+                    _scale_rect.y + _scale_rect.height / 2 + 4);
+                gdk_draw_line(_map_widget->window,
+                    _map_widget->style->fg_gc[GTK_STATE_ACTIVE],
+                    _scale_rect.x + _scale_rect.width - 4,
+                    _scale_rect.y + _scale_rect.height / 2,
+                    _scale_rect.x + (_scale_rect.width + width) / 2 + 4,
+                    _scale_rect.y + _scale_rect.height / 2);
+            }
+        }
+    }
+
+    /* Draw the compass rose, if necessary. */
+    if(_show_comprose)
+    {
+        GdkPoint points[3];
+        gint offsetx, offsety;
+        gfloat x, y;
+
+        offsetx = _comprose_rect.x;
+        offsety = _comprose_rect.y;
+
+        gdk_pixbuf_rotate_vector(&x, &y, _map_rotate_matrix, 0, 12);
+        points[0].x = offsetx + x + 0.5f; points[0].y = offsety + y + 0.5f;
+        gdk_pixbuf_rotate_vector(&x, &y, _map_rotate_matrix, 20, 30);
+        points[1].x = offsetx + x + 0.5f; points[1].y = offsety + y + 0.5f;
+        gdk_pixbuf_rotate_vector(&x, &y, _map_rotate_matrix, 0, -45);
+        points[2].x = offsetx + x + 0.5f; points[2].y = offsety + y + 0.5f;
+        gdk_pixbuf_rotate_vector(&x, &y, _map_rotate_matrix, -20, 30);
+        points[3].x = offsetx + x + 0.5f; points[3].y = offsety + y + 0.5f;
+
+        gdk_draw_polygon(_map_widget->window,
+                _map_widget->style->bg_gc[GTK_STATE_ACTIVE],
+                TRUE, /* FILLED */
+                points, 4);
+        gdk_draw_polygon(_map_widget->window,
+                _map_widget->style->fg_gc[GTK_STATE_ACTIVE],
+                FALSE, /* NOT FILLED */
+                points, 4);
+
+        gdk_draw_layout(_map_widget->window,
+                _map_widget->style->fg_gc[GTK_STATE_ACTIVE],
+                _comprose_rect.x - _comprose_rect.width / 2 + 1,
+                _comprose_rect.y - _comprose_rect.height / 2 - 4,
+                _comprose_layout);
+    }
+
+    /* Draw a stopwatch if we're redrawing the map. */
+    for(i = _redraw_count - 1; i >= 0; i--)
+    {
+        gdk_draw_pixbuf(
+                _map_widget->window,
+                _map_widget->style->fg_gc[GTK_STATE_ACTIVE],
+                _redraw_wait_icon,
+                0, 0,
+                _redraw_wait_bounds.x + i
+                        * HOURGLASS_SEPARATION,
+                _redraw_wait_bounds.y,
+                _redraw_wait_bounds.width,
+                _redraw_wait_bounds.height,
+                GDK_RGB_DITHER_NONE, 0, 0);
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static void
+latlon_cb_copy_clicked(GtkWidget *widget, LatlonDialog *lld) {
+    gchar buffer[42];
+
+    snprintf(buffer, sizeof(buffer),
+            "%s %s",
+            gtk_label_get_text(GTK_LABEL(lld->lat)),
+            gtk_label_get_text(GTK_LABEL(lld->lon)));
+
+    gtk_clipboard_set_text(
+            gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), buffer, -1);
+}
+
+static void
+latlon_cb_fmt_changed(GtkWidget *widget, LatlonDialog *lld) {
+  DegFormat fmt;
+
+  fmt = gtk_combo_box_get_active(GTK_COMBO_BOX(lld->fmt_combo));
+
+  {
+    gint old = _degformat; /* augh... */
+    gchar buffer[LL_FMT_LEN];
+
+    _degformat = fmt;
+    lat_format(lld->glat, buffer);
+    gtk_label_set_label(GTK_LABEL(lld->lat), buffer);
+    lon_format(lld->glon, buffer);
+    gtk_label_set_label(GTK_LABEL(lld->lon), buffer);
+    _degformat = old;
+  }
+}
+
+gboolean
+latlon_dialog(gdouble lat, gdouble lon)
+{
+    LatlonDialog lld;
+    GtkWidget *dialog;
+    GtkWidget *table;
+    GtkWidget *label;
+    GtkWidget *txt_lat;
+    GtkWidget *txt_lon;
+    GtkWidget *cmb_format;
+    GtkWidget *btn_copy = NULL;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    dialog = gtk_dialog_new_with_buttons(_("Show Position"),
+            GTK_WINDOW(_window), GTK_DIALOG_MODAL,
+            GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+            NULL);
+
+    /* Set the lat/lon strings. */
+    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+            table = gtk_table_new(5, 2, FALSE), TRUE, TRUE, 0);
+
+    gtk_table_attach(GTK_TABLE(table),
+            label = gtk_label_new(_("Lat")),
+            0, 1, 0, 1, GTK_FILL, 0, 2, 4);
+    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+    gtk_table_attach(GTK_TABLE(table),
+            txt_lat = gtk_label_new(""),
+            1, 2, 0, 1, GTK_FILL, 0, 2, 4);
+    gtk_misc_set_alignment(GTK_MISC(txt_lat), 1.f, 0.5f);
+
+    gtk_table_attach(GTK_TABLE(table),
+            label = gtk_label_new(_("Lon")),
+            0, 1, 1, 2, GTK_FILL, 0, 2, 4);
+    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+    gtk_table_attach(GTK_TABLE(table),
+            txt_lon = gtk_label_new(""),
+            1, 2, 1, 2, GTK_FILL, 0, 2, 4);
+    gtk_misc_set_alignment(GTK_MISC(txt_lon), 1.f, 0.5f);
+
+    gtk_table_attach(GTK_TABLE(table),
+            label = gtk_label_new(_("Format")),
+            0, 1, 2, 3, GTK_FILL, 0, 2, 4);
+    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+    gtk_table_attach(GTK_TABLE(table),
+            label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
+            1, 2, 2, 3, GTK_FILL, 0, 2, 4);
+    gtk_container_add(GTK_CONTAINER(label),
+            cmb_format = gtk_combo_box_new_text());
+    gtk_table_attach(GTK_TABLE(table),
+            btn_copy = gtk_button_new_with_label(_("Copy")),
+            0, 2, 3, 4, GTK_FILL, 0, 2, 4);
+
+    /* Lat/Lon */
+    {
+      gchar buffer[LL_FMT_LEN];
+
+      lat_format(lat, buffer);
+      gtk_label_set_label(GTK_LABEL(txt_lat), buffer);
+      lat_format(lon, buffer);
+      gtk_label_set_label(GTK_LABEL(txt_lon), buffer);
+    }
+
+    /* Fill in formats */
+    {
+      int i;
+
+      for(i = 0; i < DEG_FORMAT_ENUM_COUNT; i++) {
+          gtk_combo_box_append_text(GTK_COMBO_BOX(cmb_format),
+                  DEG_FORMAT_ENUM_TEXT[i]);
+      }
+      gtk_combo_box_set_active(GTK_COMBO_BOX(cmb_format), _degformat);
+    }
+
+
+    /* setup cb context */
+    lld.fmt_combo = cmb_format;
+    lld.glat = lat;
+    lld.glon = lon;
+    lld.lat = txt_lat;
+    lld.lon = txt_lon;
+
+    /* Connect Signals */
+    g_signal_connect(G_OBJECT(cmb_format), "changed",
+                    G_CALLBACK(latlon_cb_fmt_changed), &lld);
+    g_signal_connect(G_OBJECT(btn_copy), "clicked",
+                    G_CALLBACK(latlon_cb_copy_clicked), &lld);
+
+    gtk_widget_show_all(dialog);
+
+    gtk_dialog_run(GTK_DIALOG(dialog));
+    gtk_widget_hide_all(dialog);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+
+/**
+ * This is a multi-purpose function for allowing the user to select a file
+ * for either reading or writing.  If chooser_action is
+ * GTK_FILE_CHOOSER_ACTION_OPEN, then bytes_out and size_out must be
+ * non-NULL.  If chooser_action is GTK_FILE_CHOOSER_ACTION_SAVE, then
+ * handle_out must be non-NULL.  Either dir or file (or both) can be NULL.
+ * This function returns TRUE if a file was successfully opened.
+ */
+gboolean
+display_open_file(GtkWidget *parent, gchar **bytes_out,
+        GnomeVFSHandle **handle_out, gint *size_out,
+        gchar **dir, gchar **file, GtkFileChooserAction chooser_action)
+{
+    GtkWidget *dialog;
+    gboolean success = FALSE;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    dialog= hildon_file_chooser_dialog_new(GTK_WINDOW(_window),chooser_action);
+
+    if(dir && *dir)
+        gtk_file_chooser_set_current_folder_uri(
+                GTK_FILE_CHOOSER(dialog), *dir);
+    if(file && *file)
+    {
+        GValue val;
+        gtk_file_chooser_set_uri(
+                GTK_FILE_CHOOSER(dialog), *file);
+        if(chooser_action == GTK_FILE_CHOOSER_ACTION_SAVE)
+        {
+            /* Work around a bug in HildonFileChooserDialog. */
+            memset(&val, 0, sizeof(val));
+            g_value_init(&val, G_TYPE_BOOLEAN);
+            g_value_set_boolean(&val, FALSE);
+            g_object_set_property(G_OBJECT(dialog), "autonaming", &val);
+            gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog),
+                    strrchr(*file, '/') + 1);
+        }
+    }
+
+    gtk_widget_show_all(dialog);
+
+    while(!success && gtk_dialog_run(GTK_DIALOG(dialog))==GTK_RESPONSE_OK)
+    {
+        gchar *file_uri_str;
+        GnomeVFSResult vfs_result;
+
+        /* Get the selected filename. */
+        file_uri_str = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(dialog));
+
+        if((chooser_action == GTK_FILE_CHOOSER_ACTION_OPEN
+                && (GNOME_VFS_OK != (vfs_result = gnome_vfs_read_entire_file(
+                        file_uri_str, size_out, bytes_out))))
+                || (chooser_action == GTK_FILE_CHOOSER_ACTION_SAVE
+                    && GNOME_VFS_OK != (vfs_result = gnome_vfs_create(
+                            handle_out, file_uri_str,
+                            GNOME_VFS_OPEN_WRITE, FALSE, 0664))))
+        {
+            gchar buffer[BUFFER_SIZE];
+            snprintf(buffer, sizeof(buffer),
+                    "%s:\n%s", chooser_action == GTK_FILE_CHOOSER_ACTION_OPEN
+                                ? _("Failed to open file for reading")
+                                : _("Failed to open file for writing"),
+                    gnome_vfs_result_to_string(vfs_result));
+            popup_error(dialog, buffer);
+        }
+        else
+            success = TRUE;
+
+        g_free(file_uri_str);
+    }
+
+    if(success)
+    {
+        /* Success!. */
+        if(dir)
+        {
+            g_free(*dir);
+            *dir = gtk_file_chooser_get_current_folder_uri(
+                    GTK_FILE_CHOOSER(dialog));
+        }
+
+        /* If desired, save the file for later. */
+        if(file)
+        {
+            g_free(*file);
+            *file = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(dialog));
+        }
+    }
+
+    gtk_widget_destroy(dialog);
+
+    vprintf("%s(): return %d\n", __PRETTY_FUNCTION__, success);
+    return success;
+}
+
+void
+display_init()
+{
+    PangoContext *pango_context;
+    PangoFontDescription *pango_font;
+    GdkColor color;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    /* Cache some pango and GCs for drawing. */
+    pango_context = gtk_widget_get_pango_context(_map_widget);
+    _scale_layout = pango_layout_new(pango_context);
+    pango_font = pango_font_description_new();
+    pango_font_description_set_size(pango_font, 12 * PANGO_SCALE);
+    pango_layout_set_font_description(_scale_layout, pango_font);
+
+    /* zoom box */
+    pango_context = gtk_widget_get_pango_context(_map_widget);
+    _zoom_layout = pango_layout_new(pango_context);
+    pango_font = pango_font_description_new();
+    pango_font_description_set_size(pango_font, 12 * PANGO_SCALE);
+    pango_layout_set_font_description(_zoom_layout, pango_font);
+    pango_layout_set_alignment(_zoom_layout, PANGO_ALIGN_CENTER);
+
+    /* compose rose */
+    pango_context = gtk_widget_get_pango_context(_map_widget);
+    _comprose_layout = pango_layout_new(pango_context);
+    pango_font = pango_font_description_new();
+    pango_font_description_set_size(pango_font, 16 * PANGO_SCALE);
+    pango_font_description_set_weight(pango_font, PANGO_WEIGHT_BOLD);
+    pango_layout_set_font_description(_comprose_layout, pango_font);
+    pango_layout_set_alignment(_comprose_layout, PANGO_ALIGN_CENTER);
+    pango_layout_set_text(_comprose_layout, "N", -1);
+    {
+        PangoRectangle rect;
+        pango_layout_get_pixel_extents(_comprose_layout, &rect, NULL);
+        _comprose_rect.width = rect.width + 3;
+        _comprose_rect.height = rect.height + 3;
+    }
+
+    /* speed limit */
+    _speed_limit_gc1 = gdk_gc_new (_map_widget->window);
+    color.red = 0xffff;
+    color.green = 0;
+    color.blue = 0;
+    gdk_gc_set_rgb_fg_color(_speed_limit_gc1, &color);
+    color.red = 0;
+    color.green = 0;
+    color.blue = 0;
+    _speed_limit_gc2 = gdk_gc_new(_map_widget->window);
+    gdk_gc_set_rgb_fg_color(_speed_limit_gc2, &color);
+    pango_context = gtk_widget_get_pango_context(_map_widget);
+    _speed_limit_layout = pango_layout_new(pango_context);
+    pango_font = pango_font_description_new();
+    pango_font_description_set_size(pango_font, 64 * PANGO_SCALE);
+    pango_layout_set_font_description(_speed_limit_layout,
+            pango_font);
+    pango_layout_set_alignment(_speed_limit_layout, PANGO_ALIGN_CENTER);
+
+    /* draw_sat_info() */
+    _sat_info_gc1 = gdk_gc_new(_map_widget->window);
+    color.red = 0;
+    color.green = 0;
+    color.blue = 0;
+    gdk_gc_set_rgb_fg_color(_sat_info_gc1, &color);
+    color.red = 0;
+    color.green = 0;
+    color.blue = 0xffff;
+    _sat_info_gc2 = gdk_gc_new(_map_widget->window);
+    gdk_gc_set_rgb_fg_color(_sat_info_gc2, &color);
+    pango_context = gtk_widget_get_pango_context(_map_widget);
+    _sat_info_layout = pango_layout_new(pango_context);
+    pango_font = pango_font_description_new();
+    pango_font_description_set_family(pango_font,"Sans Serif");
+    pango_font_description_set_size(pango_font, 8*PANGO_SCALE);
+    pango_layout_set_font_description(_sat_info_layout, pango_font);
+    pango_layout_set_alignment(_sat_info_layout, PANGO_ALIGN_CENTER);
+
+    /* sat_panel_expose() */
+    pango_context = gtk_widget_get_pango_context(_map_widget);
+    _sat_panel_layout = pango_layout_new(pango_context);
+    pango_font = pango_font_description_new();
+    pango_font_description_set_family(pango_font,"Sans Serif");
+    pango_font_description_set_size(pango_font, 14*PANGO_SCALE);
+    pango_layout_set_font_description (_sat_panel_layout, pango_font);
+
+    /* heading_panel_expose() */
+    pango_context = gtk_widget_get_pango_context(_map_widget);
+    _heading_panel_layout = pango_layout_new(pango_context);
+    pango_font = pango_font_description_new();
+    pango_font_description_set_family(pango_font,"Sans Serif");
+
+    /* draw_sat_details() */
+    pango_context = gtk_widget_get_pango_context(_map_widget);
+    _sat_details_layout = pango_layout_new(pango_context);
+    pango_font = pango_font_description_new();
+    pango_font_description_set_family(pango_font,"Sans Serif");
+    pango_font_description_set_size(pango_font, 10*PANGO_SCALE);
+    pango_layout_set_font_description(_sat_details_layout,
+            pango_font);
+    pango_layout_set_alignment(_sat_details_layout, PANGO_ALIGN_CENTER);
+
+    /* sat_details_panel_expose() */
+    pango_context = gtk_widget_get_pango_context(_map_widget);
+    _sat_details_expose_layout = pango_layout_new(pango_context);
+    pango_font = pango_font_description_new();
+    pango_font_description_set_family(
+            pango_font,"Sans Serif");
+    pango_layout_set_alignment(_sat_details_expose_layout,
+            PANGO_ALIGN_CENTER);
+    pango_font_description_set_size(pango_font,
+            14*PANGO_SCALE);
+    pango_layout_set_font_description(_sat_details_expose_layout,
+            pango_font);
+
+    /* Load the _redraw_wait_icon. */
+    {
+        GError *error = NULL;
+        gchar *icon_path = "/usr/share/icons/hicolor/scalable/hildon"
+                           "/qgn_list_gene_image_file_wait.png";
+        _redraw_wait_bounds.x = 0;
+        _redraw_wait_bounds.y = 0;
+        _redraw_wait_icon = gdk_pixbuf_new_from_file(icon_path, &error);
+        if(!_redraw_wait_icon || error)
+        {
+            printf("Error parsing pixbuf: %s\n",
+                    error ? error->message : icon_path);
+            _redraw_wait_bounds.width = 0;
+            _redraw_wait_bounds.height = 0;
+            _redraw_wait_icon = NULL;
+        }
+        else
+        {
+            _redraw_wait_bounds.width
+                = gdk_pixbuf_get_width(_redraw_wait_icon);
+            _redraw_wait_bounds.height
+                = gdk_pixbuf_get_height(_redraw_wait_icon);
+        }
+    }
+
+    g_signal_connect(G_OBJECT(_map_widget), "configure_event",
+            G_CALLBACK(map_cb_configure), NULL);
+
+    g_signal_connect(G_OBJECT(_map_widget), "expose_event",
+            G_CALLBACK(map_cb_expose), NULL);
+    g_signal_connect(G_OBJECT(_sat_panel), "expose_event",
+            G_CALLBACK(sat_panel_expose), NULL);
+    g_signal_connect(G_OBJECT(_heading_panel), "expose_event",
+            G_CALLBACK(heading_panel_expose), NULL);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
diff --git a/src/display.h b/src/display.h
new file mode 100644 (file)
index 0000000..64f0d2d
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAEMO_MAPPER_DISPLAY_H
+#define MAEMO_MAPPER_DISPLAY_H
+
+typedef struct {
+    gdouble glat, glon;
+    GtkWidget *fmt_combo;
+    GtkWidget *lat;
+    GtkWidget *lon;
+} LatlonDialog;
+
+
+gboolean gps_display_details(void);
+void gps_display_data(void);
+void gps_hide_text(void);
+void gps_show_info(void);
+void gps_details(void);
+
+void map_render_segment(GdkGC *gc_norm, GdkGC *gc_alt,
+        gint unitx1, gint unity1, gint unitx2, gint unity2);
+void map_render_paths();
+
+void update_gcs();
+
+gboolean window_present();
+
+void map_pan(gint delta_unitx, gint delta_unity);
+void map_move_mark();
+void map_refresh_mark(gboolean force_redraw);
+void map_force_redraw();
+
+
+void map_center_unit_full(Point new_center, gint zoom, gint rotate_angle);
+void map_center_unit(Point new_center);
+void map_center_rotate(gint rotate_angle);
+void map_center_zoom(gint zoom);
+
+gboolean map_download_refresh_idle(MapUpdateTask *mut);
+void map_set_zoom(gint new_zoom);
+
+gboolean thread_render_map(MapRenderTask *mrt);
+
+gboolean map_cb_configure(GtkWidget *widget, GdkEventConfigure *event);
+gboolean map_cb_expose(GtkWidget *widget, GdkEventExpose *event);
+
+gboolean latlon_dialog(gdouble lat, gdouble lon);
+
+gboolean display_open_file(GtkWidget *parent, gchar **bytes_out,
+        GnomeVFSHandle **handle_out, gint *size_out, gchar **dir, gchar **file,
+        GtkFileChooserAction chooser_action);
+
+void display_init();
+
+#endif /* ifndef MAEMO_MAPPER_DISPLAY_H */
diff --git a/src/gdk-pixbuf-rotate.c b/src/gdk-pixbuf-rotate.c
new file mode 100644 (file)
index 0000000..70409df
--- /dev/null
@@ -0,0 +1,571 @@
+/* GdkPixbuf library - image transformation using 2x2 arbitrary matrix
+ *
+ * Copyright (C) 1999 The Free Software Foundation
+ *
+ * Authors: Oleg Klimov <quif@land.ru>, John Costigan
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* 1997-1999  original code was written
+ * 2001-08-12 ported to GdkImage
+ * 2003-01-31 ported to GdkPixbuf
+ */
+
+#define _GNU_SOURCE
+
+#include <math.h>
+#include "gdk-pixbuf-rotate.h"
+
+/**
+ * gdk_pixbuf_rotate_matrix_new:
+ *
+ * Creates a new 2x2 matrix. Allocates 4*sizeof(gfloat) buffer,
+ * fills it with 1 on the main dialonal.
+ * | 1 0 |
+ * | 0 1 |
+ * Static gfloat[4] buffer can be used instead.
+ *
+ * Return value: initialized matrix, destroy with g_free()
+ **/
+gfloat*
+gdk_pixbuf_rotate_matrix_new()
+{
+    gfloat* matrix;
+    matrix = g_malloc(sizeof(gfloat)*4);
+    matrix[0] = 1; matrix[1] = 0;
+    matrix[2] = 0; matrix[3] = 1;
+    return matrix;
+}
+
+/**
+ * gdk_pixbuf_rotate_matrix_fill_for_rotation:
+ * @matrix: destination matrix
+ * @angle: angle (radian)
+ *
+ * Prepare 2x2 matrix for rotation.
+ * | cosf(a) -sinf(a) |
+ * | sinf(a)  cosf(a) |
+ **/
+void
+gdk_pixbuf_rotate_matrix_fill_for_rotation(gfloat* matrix, gfloat angle)
+{
+    gfloat sa = sinf(angle), ca = cosf(angle);
+    matrix[0] = ca; matrix[1] = -sa;
+    matrix[2] = sa; matrix[3] = ca;
+}
+
+/**
+ * gdk_pixbuf_rotate_matrix_mult_number:
+ * @matrix: matrix to multiply
+ * @mult: multiplier
+ *
+ * Multiply 2x2 matrix.
+ * | *=mult *=mult |
+ * | *=mult *=mult |
+ * Use to scale image.
+ **/
+void
+gdk_pixbuf_rotate_matrix_mult_number(gfloat* matrix, gfloat mult)
+{
+    matrix[0] *= mult; matrix[1] *= mult;
+    matrix[2] *= mult; matrix[3] *= mult;
+}
+
+/**
+ * gdk_pixbuf_rotate_matrix_mult_matrix:
+ * @dst: matrix to store the result
+ * @src1: left matrix to multiply
+ * @src2: right matrix to multiply
+ *
+ * Multiply two 2x2 matrixes. Destination and any of the
+ * sources can be one the same.
+ * Use to combine two transformations.
+ **/
+void
+gdk_pixbuf_rotate_matrix_mult_matrix(
+    gfloat* dst,
+    const gfloat* src1, const gfloat* src2)
+{
+    gfloat ans[4];
+    ans[0] = src1[0]*src2[0] + src1[1]*src2[2];
+    ans[1] = src1[0]*src2[1] + src1[1]*src2[3];
+    ans[2] = src1[2]*src2[0] + src1[3]*src2[2];
+    ans[3] = src1[2]*src2[1] + src1[3]*src2[3];
+    dst[0] = ans[0];
+    dst[1] = ans[1];
+    dst[2] = ans[2];
+    dst[3] = ans[3];
+}
+
+/**
+ * gdk_pixbuf_rotate_vector:
+ * @dst_x: pointer to store X coord of the result vector
+ * @dst_y: pointer to store Y coord of the result vector
+ * @matrix: matrix to use
+ * @src_x: X coord of source vector
+ * @src_y: Y coord of source vector
+ *
+ * Convenience: the same matrix for transforming vectors.
+ * Imagine you have a spaceship image, you rotate it and
+ * now want to calculate where its spaceguns located.
+ **/
+void
+gdk_pixbuf_rotate_vector(
+    gfloat* dst_x, gfloat* dst_y,
+    const gfloat* matrix,
+    gfloat src_x, gfloat src_y)
+{
+    *dst_x = matrix[0]*src_x + matrix[1]*src_y;
+    *dst_y = matrix[2]*src_x + matrix[3]*src_y;
+}
+
+inline gfloat gfloat_abs(gfloat d) { return d>0 ? d : -d; } 
+inline gfloat gfloat_min(gfloat a, gfloat b) { return a>b ? b : a; } 
+inline gfloat gfloat_max(gfloat a, gfloat b) { return a>b ? a : b; } 
+
+/**
+ * gdk_pixbuf_rotate_matrix_reverse:
+ * @dest: matrix to store the result
+ * @src: matrix to reverse
+ *
+ * Calculates reversed matrix.
+ *
+ * Return value: TRUE on success, FALSE when reverse
+ * matrix doen't exist.
+ **/
+gboolean
+gdk_pixbuf_rotate_matrix_reverse(gfloat* dest, const gfloat* src)
+{
+    gfloat ans[4];
+    gfloat det;
+    gfloat consider_as_zero;
+    det = gdk_pixbuf_rotate_matrix_determinant(src);
+    consider_as_zero =
+        (gfloat_abs(src[0]) +
+         gfloat_abs(src[1]) +
+         gfloat_abs(src[2]) +
+         gfloat_abs(src[3])) * 1e-11;
+    if (gfloat_abs(det)<consider_as_zero) return FALSE;
+    ans[0] = src[3];
+    ans[1] = -src[1];
+    ans[2] = -src[2];
+    ans[3] = src[0];
+    gdk_pixbuf_rotate_matrix_mult_number(ans, 1.0/det);
+    dest[0] = ans[0];
+    dest[1] = ans[1];
+    dest[2] = ans[2];
+    dest[3] = ans[3];
+    return TRUE;
+}
+
+/**
+ * gdk_pixbuf_rotate_matrix_transpose:
+ * @dest: matrix to store the result
+ * @src: matrix to transpose
+ *
+ * Calculates transposed matrix.
+ **/
+void
+gdk_pixbuf_rotate_matrix_transpose(
+    gfloat* dest,
+    const gfloat* src)
+{
+    gfloat t;
+    t = dest[2];
+    dest[2] = dest[1];
+    dest[1] = t;
+}
+
+/**
+ * gdk_pixbuf_rotate_matrix_determinant:
+ * @matrix: matrix
+ *
+ * Calculates determinant.
+ *
+ * Return value: determinant.
+ **/
+gfloat
+gdk_pixbuf_rotate_matrix_determinant(const gfloat* matrix)
+{
+    return matrix[0]*matrix[3] - matrix[1]*matrix[2];
+}
+
+
+#define ROTATE_CUT_EDGES (0.0) /* cut small part of texel on edges - to avoid artefacts */
+
+/**
+ * gdk_pixbuf_rotate:
+ * @dst_pixbuf: destination pixbuf
+ * @dst_x: X coord in @dst_pixbuf
+ * @dst_y: Y coord in @dst_pixbuf
+ * @matrix: transformation matrix
+ * @src_pixbuf: a pixbuf
+ * @src_center_x: X coord of center in @src_pixbuf
+ * @src_center_y: Y coord of center in @src_pixbuf
+ * @result_rect_x: pointer to X coord of rectangle to store result bounds
+ * @result_rect_y: pointer to Y coord of rectangle to store result bounds
+ * @result_rect_width: pointer to Width of rectangle to store result bounds
+ * @result_rect_height: pointer to Height of rectangle to store result bounds
+ * @interp_type: GDK_INTERP_NEAREST
+ *
+ * Transform a src_pixbuf into dst_pixbuf using arbitrary matrix.
+ * GDK_INTERP_NEAREST only supported
+ * GDK_COLORSPACE_RGB only supported
+ * only 8 bits per sample supported
+ * only 3 or 4 channels supported (with or without alpha)
+ **/
+void
+gdk_pixbuf_rotate(
+    GdkPixbuf* dst_pixbuf, gfloat dst_x, gfloat dst_y,
+    gfloat* matrix,
+    GdkPixbuf* src_pixbuf, gfloat src_center_x, gfloat src_center_y,
+    gfloat src_width, gfloat src_height,
+    gint* result_rect_x,
+    gint* result_rect_y,
+    gint* result_rect_width,
+    gint* result_rect_height)
+{
+    guint dst_width, dst_height;
+    gfloat reverse[4];
+    guchar *dst_buf, *dst;
+    guint dst_n_channels;
+    guchar *src_buf, *src;
+    guint src_n_channels;
+    gint src_bpl;
+    gint dst_bpl;
+
+    gboolean lines4 = TRUE;     /* two cases: 4-lines or 2-lines */
+    gfloat px[4], py[4];        /* edge points on dest */
+    gint line_l1, line_l2 = -1; /* line indexes, 2 left + 2 right
+                                 *            or 1 left + 1 right */
+    gint line_r1, line_r2 = -1;
+    gfloat k[4], b[4];          /* x = k*y + b - bounding line equations */
+    gint ili = -1;              /* invalid line index - to restore which
+                                 * 2 lines valid [2-lines case] */
+
+    gfloat left, right, top, bottom;    /* resulting rect */
+    gint int_left, int_right, int_top, int_bottom;
+    gint li =0, ri =0, ti =0, bi =0;    /* point indexes */
+
+    gfloat src_x, src_y;                    /* first point in a row */
+    gfloat pixel_right_x, pixel_right_y;    /* one-pixel-to-the-left
+                                             * vector on source */
+    gint32  pixel_right_ix, pixel_right_iy; /* fixed-point, the same */
+
+    gint c, x, y; /* bunch of temprorary variables */
+    gfloat tmpd;
+    gint tmpi;
+
+
+#if 0
+    printf("%s(%p, %f, %f, [%f, %f, %f, %f], %p, %f, %f, %f, %f)\n",
+            __PRETTY_FUNCTION__, dst_pixbuf, dst_x, dst_y,
+            matrix[0], matrix[1], matrix[2], matrix[3],
+            src_pixbuf, src_center_x, src_center_y,
+            src_width, src_height);
+#endif
+
+dst_width = gdk_pixbuf_get_width(dst_pixbuf);
+dst_height = gdk_pixbuf_get_height(dst_pixbuf);
+
+    if (!gdk_pixbuf_rotate_matrix_reverse(reverse, matrix)) return;
+    /* No reverse matrix means we have image collapsed into
+     * line or point
+     */
+
+    src_buf = gdk_pixbuf_get_pixels(src_pixbuf);
+    dst_buf = gdk_pixbuf_get_pixels(dst_pixbuf);
+    src_bpl = gdk_pixbuf_get_rowstride(src_pixbuf);
+    dst_bpl = gdk_pixbuf_get_rowstride(dst_pixbuf);
+    src_n_channels = gdk_pixbuf_get_n_channels(src_pixbuf);
+    dst_n_channels = gdk_pixbuf_get_n_channels(dst_pixbuf);
+
+    /* 01  map source edge points to dest
+     * 32
+     */
+    gdk_pixbuf_rotate_vector(&px[0], &py[0], matrix,
+        (src_width / -2.f), (src_height / -2.f));
+    gdk_pixbuf_rotate_vector(&px[1], &py[1], matrix,
+        (src_width / 2.f), (src_height / -2.f));
+    gdk_pixbuf_rotate_vector(&px[2], &py[2], matrix,
+        (src_width / 2.f), (src_height / 2.f));
+    gdk_pixbuf_rotate_vector(&px[3], &py[3], matrix,
+        (src_width / -2.f), (src_height / 2.f));
+#if 0
+    gdk_pixbuf_rotate_vector(&px[0], &py[0], matrix,
+        - src_center_x + ROTATE_CUT_EDGES,
+        - src_center_y + ROTATE_CUT_EDGES);
+    gdk_pixbuf_rotate_vector(&px[1], &py[1], matrix,
+        src_width - src_center_x - ROTATE_CUT_EDGES,
+        - src_center_y + ROTATE_CUT_EDGES);
+    gdk_pixbuf_rotate_vector(&px[2], &py[2], matrix,
+        src_width - src_center_x -ROTATE_CUT_EDGES,
+        src_height - src_center_y - ROTATE_CUT_EDGES);
+    gdk_pixbuf_rotate_vector(&px[3], &py[3], matrix,
+        - src_center_x + ROTATE_CUT_EDGES,
+        src_height - src_center_y - ROTATE_CUT_EDGES);
+#endif
+
+    for (c=0; c<4; c++) {
+        tmpi = (c+1)%4;
+        tmpd = py[tmpi] - py[c];
+        if (gfloat_abs(tmpd)<1e-4) {
+            lines4 = FALSE;
+            ili = c;
+        } else {
+            k[c] = (px[tmpi]-px[c])/tmpd;
+            b[c] = px[c] - k[c]*py[c];
+        }
+    }
+
+    left = px[0];
+    right = px[0];
+    top = py[0];
+    bottom = py[0];
+    for (c=1; c<4; c++) {
+        if (left>=px[c]) { left = px[c]; li = c; }
+        if (right<=px[c]) { right = px[c]; ri = c; }
+        if (top>=py[c]) { top = py[c]; ti = c; }
+        if (bottom<=py[c]) { bottom = py[c]; bi = c; }
+    }
+    int_top = (gint) (dst_y + py[ti] + 0.5);
+    int_top = CLAMP(int_top, 0, (gint)dst_height);
+    int_bottom = (gint) (dst_y + py[bi] + 0.5);
+    int_bottom = CLAMP(int_bottom, 0, (gint)dst_height);
+    int_left = (gint) (dst_x + px[li] + 0.5);
+    int_left = CLAMP(int_left, 0, (gint)dst_width);
+    int_right = (gint) (dst_x + px[ri] + 0.5);
+    int_right = CLAMP(int_right, 0, (gint)dst_width);
+    if (result_rect_x) *result_rect_x = int_left;
+    if (result_rect_y) *result_rect_y = int_top;
+    if (result_rect_width) *result_rect_width = int_right - int_left;
+    if (result_rect_height) *result_rect_height = int_bottom - int_top;
+
+    if (int_right - int_left == 0 || int_bottom - int_top == 0) return;
+
+    if (lines4) {
+        line_l1 = li;
+        line_r1 = ri;
+        /*    ti
+         *  li    ri
+         *      bi
+         */
+        if (((ti+1)%4)==ri) {
+            line_l2 = bi; /* clockwise */
+            line_r2 = ti;
+            /*   line_l1 /\  line_r2
+             *       \  \ 
+             *    line_l2  \/  line_r1
+             */
+        } else {
+            line_l2 = ti; /* anticlockwise */
+            line_r2 = bi;
+            /*   line_l2 /\  line_r1
+             *       \  \ 
+             *    line_l1  \/  line_r2
+             */
+        }
+    } else {
+        /* 2 lines case
+         *      |   |
+         * line_l1  |   |  line_r1
+         */
+        tmpd = (px[0]+px[1]+px[2]+px[3])/4.0; /* middle x */
+        tmpi = (ili+1)%4; /* valid for sure */
+        if (px[tmpi]<tmpd) {
+            line_l1 = tmpi;
+            line_r1 = (ili+3)%4;
+        } else {
+            line_r1 = tmpi;
+            line_l1 = (ili+3)%4;
+        }
+    }
+
+    gdk_pixbuf_rotate_vector(
+        &pixel_right_x, &pixel_right_y,
+        reverse,
+        1, 0);
+    pixel_right_ix = (gint32) (pixel_right_x*0x10000);
+    pixel_right_iy = (gint32) (pixel_right_y*0x10000);
+
+    for (y=int_top; y<int_bottom; y++) {
+        gfloat x1r, x2r;
+        gint x1, x2;
+        gint32 pixel_ix, pixel_iy;
+
+        /* calc line x1..x2 on dest */
+        tmpd = y - dst_y;
+        if (lines4) {
+            x1r = gfloat_max(
+                k[line_l1]*(tmpd+0.5) + b[line_l1],
+                k[line_l2]*(tmpd+0.5) + b[line_l2] );
+            x2r = gfloat_min(
+                k[line_r1]*(tmpd+0.5) + b[line_r1],
+                k[line_r2]*(tmpd+0.5) + b[line_r2] );
+        } else {
+            x1r = k[line_l1]*tmpd + b[line_l1];
+            x2r = k[line_r1]*tmpd + b[line_r1];
+        }
+        x1r += dst_x;
+        x2r += dst_x;
+        x1r = gfloat_max(x1r, 0);
+        x2r = gfloat_min(x2r, dst_width);
+        x1 = (gint) (x1r+0.5);
+        x2 = (gint) (x2r+0.5);
+        if (x2<=x1) continue;
+
+        /* calc y:x1 point on source */
+        gdk_pixbuf_rotate_vector(
+            &src_x, &src_y,
+            reverse,
+            x1-dst_x + 0.5,
+            tmpd + 0.5);
+        src_x += src_center_x;
+        src_y += src_center_y;
+
+        /* fixed point */
+        pixel_ix = (gint32) (src_x*0x10000);
+        pixel_iy = (gint32) (src_y*0x10000);
+
+        dst = dst_buf + (y*dst_bpl + x1*dst_n_channels);
+
+#define INNER_LOOP(DST_CHANNELS, SRC_CHANNELS) \
+        for (x=x1; x<x2; x++) { \
+            src = src_buf \
+                + (pixel_iy>>16)*src_bpl \
+                + (pixel_ix>>16)*SRC_CHANNELS; \
+            if (DST_CHANNELS==3 && SRC_CHANNELS==3) { \
+                dst[0] = src[0]; \
+                dst[1] = src[1]; \
+                dst[2] = src[2]; \
+            } \
+            if (DST_CHANNELS==4 && SRC_CHANNELS==3) { \
+                dst[0] = src[0]; \
+                dst[1] = src[1]; \
+                dst[2] = src[2]; \
+                dst[3] = 0xFF; \
+            } \
+            if (DST_CHANNELS==3 && SRC_CHANNELS==4) { \
+                guint a0, a1, t; \
+                a0 = (guint) src[3]; \
+                a1 = 0xff - a0; \
+                t = a0*src[0] + a1*dst[0] + 0x80; \
+                dst[0] = (t + (t>>8)) >> 8; \
+                t = a0*src[1] + a1*dst[1] + 0x80; \
+                dst[1] = (t + (t>>8)) >> 8; \
+                t = a0*src[2] + a1*dst[2] + 0x80; \
+                dst[2] = (t + (t>>8)) >> 8; \
+            } \
+            if (DST_CHANNELS==4 && SRC_CHANNELS==4) { \
+                guint a0 = (guint) src[3]; \
+                if (a0==255) { \
+                    dst[0] = src[0]; \
+                    dst[1] = src[1]; \
+                    dst[2] = src[2]; \
+                    dst[3] = 0xFF; \
+                } if (a0>0) { \
+                    guint w0 = 0xff * a0; \
+                    guint w1 = (0xff - a0) * dst[3]; \
+                    guint w = w0 + w1; \
+                    dst[0] = (w0*src[0] + w1*dst[0]) / w; \
+                    dst[1] = (w0*src[1] + w1*dst[1]) / w; \
+                    dst[2] = (w0*src[2] + w1*dst[2]) / w; \
+                    dst[3] = w / 0xff; \
+                } \
+            } \
+            pixel_ix += pixel_right_ix; \
+            pixel_iy += pixel_right_iy; \
+            dst += DST_CHANNELS; \
+        }
+
+        if (dst_n_channels==3 && src_n_channels==3) {
+            for (x=x1; x<x2; x++) {
+                src = src_buf
+                    + (pixel_iy>>16)*src_bpl
+                    + (pixel_ix>>16)*3;
+                dst[0] = src[0];
+                dst[1] = src[1];
+                dst[2] = src[2];
+                pixel_ix += pixel_right_ix;
+                pixel_iy += pixel_right_iy;
+                dst += 3;
+            }
+        }
+        else if (dst_n_channels==3 && src_n_channels==4) {
+            for (x=x1; x<x2; x++) {
+                guint a0, a1, t;
+                src = src_buf
+                    + (pixel_iy>>16)*src_bpl
+                    + (pixel_ix>>16)*4;
+                a0 = (guint) src[3];
+                a1 = 0xff - a0;
+                t = a0*src[0] + a1*dst[0] + 0x80;
+                dst[0] = (t + (t>>8)) >> 8;
+                t = a0*src[1] + a1*dst[1] + 0x80;
+                dst[1] = (t + (t>>8)) >> 8;
+                t = a0*src[2] + a1*dst[2] + 0x80;
+                dst[2] = (t + (t>>8)) >> 8;
+                pixel_ix += pixel_right_ix;
+                pixel_iy += pixel_right_iy;
+                dst += 3;
+            }
+        }
+        else if (dst_n_channels==4 && src_n_channels==3)
+        {
+            for (x=x1; x<x2; x++) {
+                src = src_buf
+                    + (pixel_iy>>16)*src_bpl
+                    + (pixel_ix>>16)*3;
+                dst[0] = src[0];
+                dst[1] = src[1];
+                dst[2] = src[2];
+                dst[3] = 0xFF;
+                pixel_ix += pixel_right_ix;
+                pixel_iy += pixel_right_iy;
+                dst += 4;
+            }
+        }
+        else if (dst_n_channels==4 && src_n_channels==4)
+        {
+            for (x=x1; x<x2; x++) {
+                guint a0;
+                src = src_buf
+                    + (pixel_iy>>16)*src_bpl
+                    + (pixel_ix>>16)*4;
+                a0 = (guint) src[3];
+                if (a0==255) {
+                    dst[0] = src[0];
+                    dst[1] = src[1];
+                    dst[2] = src[2];
+                    dst[3] = 0xFF;
+                } if (a0>0) {
+                    guint w0 = 0xff * a0;
+                    guint w1 = (0xff - a0) * dst[3];
+                    guint w = w0 + w1;
+                    dst[0] = (w0*src[0] + w1*dst[0]) / w;
+                    dst[1] = (w0*src[1] + w1*dst[1]) / w;
+                    dst[2] = (w0*src[2] + w1*dst[2]) / w;
+                    dst[3] = w / 0xff;
+                }
+                pixel_ix += pixel_right_ix;
+                pixel_iy += pixel_right_iy;
+                dst += 4;
+            }
+        }
+    }
+}
+
diff --git a/src/gdk-pixbuf-rotate.h b/src/gdk-pixbuf-rotate.h
new file mode 100644 (file)
index 0000000..997705a
--- /dev/null
@@ -0,0 +1,68 @@
+/* GdkPixbuf library - image transformation using 2x2 arbitrary matrix
+ *
+ * Copyright (C) 1999 The Free Software Foundation
+ *
+ * Authors: Oleg Klimov <quif@land.ru>, John Costigan
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GDK_PIXBUF_ROTATE_H
+#define GDK_PIXBUF_ROTATE_H
+
+#include "gdk-pixbuf/gdk-pixbuf.h"
+
+G_BEGIN_DECLS
+
+
+gfloat* gdk_pixbuf_rotate_matrix_new            ();
+void gdk_pixbuf_rotate_matrix_fill_for_rotation (gfloat*       matrix,
+                                                 gfloat        angle);
+void gdk_pixbuf_rotate_matrix_mult_number       (gfloat*       matrix,
+                                                 gfloat        mult);
+void gdk_pixbuf_rotate_matrix_mult_matrix       (gfloat*       dst_matrix,
+                                                 const gfloat* src1,
+                                                 const gfloat* src2);
+gboolean gdk_pixbuf_rotate_matrix_reverse       (gfloat*       dest,
+                                                 const gfloat* src);
+void gdk_pixbuf_rotate_matrix_transpose         (gfloat*       dest,
+                                                 const gfloat* src);
+gfloat gdk_pixbuf_rotate_matrix_determinant     (const gfloat* matrix);
+
+
+void gdk_pixbuf_rotate          (GdkPixbuf*    dst,
+                                 gfloat        dst_x,
+                                 gfloat        dst_y,
+                                 gfloat*       matrix,
+                                 GdkPixbuf*    src,
+                                 gfloat        src_center_x,
+                                 gfloat        src_center_y,
+                                 gfloat        src_width,
+                                 gfloat        src_height,
+                                 gint* result_rect_x,
+                                 gint* result_rect_y,
+                                 gint* result_rect_width,
+                                 gint* result_rect_height);
+void gdk_pixbuf_rotate_vector   (gfloat*        dst_x,
+                                 gfloat*        dst_y,
+                                 const gfloat*  matrix,
+                                 gfloat         src_vector_x,
+                                 gfloat         src_vector_y);
+
+G_END_DECLS
+
+#endif /* GDK_PIXBUF_ROTATE_H */
+
diff --git a/src/gps.c b/src/gps.c
new file mode 100644 (file)
index 0000000..a0230ff
--- /dev/null
+++ b/src/gps.c
@@ -0,0 +1,964 @@
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define _GNU_SOURCE
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <dbus/dbus-glib.h>
+#include <bt-dbus.h>
+#include <hildon-widgets/hildon-note.h>
+#include <hildon-widgets/hildon-banner.h>
+#include <libgnomevfs/gnome-vfs.h>
+#include <libgnomevfs/gnome-vfs-inet-connection.h>
+
+#include "types.h"
+#include "data.h"
+#include "defines.h"
+
+#include "display.h"
+#include "gps.h"
+#include "path.h"
+#include "util.h"
+
+
+#define GPS_READ_BUF_SIZE 128
+
+static void rcvr_connect_response(DBusGProxy *proxy, DBusGProxyCall *call_id);
+
+static volatile GThread *_gps_thread = NULL;
+static GMutex *_gps_init_mutex = NULL;
+static volatile gint _gps_rcvr_retry_count = 0;
+static DBusGProxy *_rfcomm_req_proxy = NULL;
+
+static gint _gmtoffset = 0;
+
+
+#define MACRO_PARSE_INT(tofill, str) { \
+    gchar *error_check; \
+    (tofill) = strtol((str), &error_check, 10); \
+    if(error_check == (str)) \
+    { \
+        g_printerr("Line %d: Failed to parse string as int: %s\n", \
+                __LINE__, str); \
+        MACRO_BANNER_SHOW_INFO(_window, \
+                _("Invalid NMEA input from receiver!")); \
+        return; \
+    } \
+}
+#define MACRO_PARSE_FLOAT(tofill, str) { \
+    gchar *error_check; \
+    (tofill) = g_ascii_strtod((str), &error_check); \
+    if(error_check == (str)) \
+    { \
+        g_printerr("Failed to parse string as float: %s\n", str); \
+        MACRO_BANNER_SHOW_INFO(_window, \
+                _("Invalid NMEA input from receiver!")); \
+        return; \
+    } \
+}
+static void
+gps_parse_rmc(gchar *sentence)
+{
+    /* Recommended Minimum Navigation Information C
+     *  1) UTC Time
+     *  2) Status, V=Navigation receiver warning A=Valid
+     *  3) Latitude
+     *  4) N or S
+     *  5) Longitude
+     *  6) E or W
+     *  7) Speed over ground, knots
+     *  8) Track made good, degrees true
+     *  9) Date, ddmmyy
+     * 10) Magnetic Variation, degrees
+     * 11) E or W
+     * 12) FAA mode indicator (NMEA 2.3 and later)
+     * 13) Checksum
+     */
+    gchar *token, *dpoint, *gpsdate = NULL;
+    gdouble tmpd = 0.f;
+    gint tmpi = 0;
+    gboolean newly_fixed = FALSE;
+    vprintf("%s(): %s\n", __PRETTY_FUNCTION__, sentence);
+
+#define DELIM ","
+
+    /* Parse time. */
+    token = strsep(&sentence, DELIM);
+    if(token && *token)
+        gpsdate = token;
+
+    token = strsep(&sentence, DELIM);
+    /* Token is now Status. */
+    if(token && *token == 'A')
+    {
+        /* Data is valid. */
+        if(_gps_state < RCVR_FIXED)
+        {
+            newly_fixed = TRUE;
+            set_conn_state(RCVR_FIXED);
+        }
+    }
+    else
+    {
+        /* Data is invalid - not enough satellites?. */
+        if(_gps_state > RCVR_UP)
+        {
+            set_conn_state(RCVR_UP);
+            track_insert_break(FALSE);
+        }
+    }
+
+    /* Parse the latitude. */
+    token = strsep(&sentence, DELIM);
+    if(token && *token)
+    {
+        dpoint = strchr(token, '.');
+        if(!dpoint) /* handle buggy NMEA */
+            dpoint = token + strlen(token);
+        MACRO_PARSE_FLOAT(tmpd, dpoint - 2);
+        dpoint[-2] = '\0';
+        MACRO_PARSE_INT(tmpi, token);
+        _gps.lat = tmpi + (tmpd * (1.0 / 60.0));
+    }
+
+    /* Parse N or S. */
+    token = strsep(&sentence, DELIM);
+    if(token && *token == 'S')
+        _gps.lat = -_gps.lat;
+
+    /* Parse the longitude. */
+    token = strsep(&sentence, DELIM);
+    if(token && *token)
+    {
+        dpoint = strchr(token, '.');
+        if(!dpoint) /* handle buggy NMEA */
+            dpoint = token + strlen(token);
+        MACRO_PARSE_FLOAT(tmpd, dpoint - 2);
+        dpoint[-2] = '\0';
+        MACRO_PARSE_INT(tmpi, token);
+        _gps.lon = tmpi + (tmpd * (1.0 / 60.0));
+    }
+
+    /* Parse E or W. */
+    token = strsep(&sentence, DELIM);
+    if(token && *token == 'W')
+        _gps.lon = -_gps.lon;
+
+    /* Parse speed over ground, knots. */
+    token = strsep(&sentence, DELIM);
+    if(token && *token)
+    {
+        MACRO_PARSE_FLOAT(_gps.speed, token);
+        if(_gps.fix > 1)
+            _gps.maxspeed = MAX(_gps.maxspeed, _gps.speed);
+    }
+
+    /* Parse heading, degrees from true north. */
+    token = strsep(&sentence, DELIM);
+    if(token && *token)
+    {
+        MACRO_PARSE_FLOAT(_gps.heading, token);
+    }
+
+    /* Parse date. */
+    token = strsep(&sentence, DELIM);
+    if(token && *token && gpsdate)
+    {
+        struct tm time;
+        gpsdate[6] = '\0'; /* Make sure time is 6 chars long. */
+        strcat(gpsdate, token);
+        strptime(gpsdate, "%H%M%S%d%m%y", &time);
+        _pos.time = mktime(&time) + _gmtoffset;
+    }
+    else
+        _pos.time = time(NULL);
+
+    /* Translate data into integers. */
+    latlon2unit(_gps.lat, _gps.lon, _pos.unitx, _pos.unity);
+
+    /* Add new data to track. */
+    if(_gps_state == RCVR_FIXED)
+    {
+        if(track_add(_pos.time, newly_fixed))
+        {
+            /* Move mark to new location. */
+            map_refresh_mark(FALSE);
+        }
+        else
+        {
+            map_move_mark();
+        }
+    }
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+static void
+gps_parse_gga(gchar *sentence)
+{
+    /* GGA          Global Positioning System Fix Data
+     1. Fix Time
+     2. Latitude
+     3. N or S
+     4. Longitude
+     5. E or W
+     6. Fix quality
+                   0 = invalid
+                   1 = GPS fix (SPS)
+                   2 = DGPS fix
+                   3 = PPS fix
+                   4 = Real Time Kinematic
+                   5 = Float RTK
+                   6 = estimated (dead reckoning) (2.3 feature)
+                   7 = Manual input mode
+                   8 = Simulation mode
+     7. Number of satellites being tracked
+     8. Horizontal dilution of position
+     9. Altitude, Meters, above mean sea level
+     10. Alt unit (meters)
+     11. Height of geoid (mean sea level) above WGS84 ellipsoid
+     12. unit
+     13. (empty field) time in seconds since last DGPS update
+     14. (empty field) DGPS station ID number
+     15. the checksum data
+     */
+    gchar *token;
+    vprintf("%s(): %s\n", __PRETTY_FUNCTION__, sentence);
+
+#define DELIM ","
+
+    /* Skip Fix time */
+    token = strsep(&sentence, DELIM);
+    /* Skip latitude */
+    token = strsep(&sentence, DELIM);
+    /* Skip N or S */
+    token = strsep(&sentence, DELIM);
+    /* Skip longitude */
+    token = strsep(&sentence, DELIM);
+    /* Skip S or W */
+    token = strsep(&sentence, DELIM);
+
+    /* Parse Fix quality */
+    token = strsep(&sentence, DELIM);
+    if(token && *token)
+        MACRO_PARSE_INT(_gps.fixquality, token);
+
+    /* Skip number of satellites */
+    token = strsep(&sentence, DELIM);
+
+    /* Parse Horizontal dilution of position */
+    token = strsep(&sentence, DELIM);
+    if(token && *token)
+        MACRO_PARSE_INT(_gps.hdop, token);
+
+    /* Altitude */
+    token = strsep(&sentence, DELIM);
+    if(token && *token)
+    {
+        MACRO_PARSE_FLOAT(_pos.altitude, token);
+    }
+    else
+        _pos.altitude = 0;
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+static void
+gps_parse_gsa(gchar *sentence)
+{
+    /* GPS DOP and active satellites
+     *  1) Auto selection of 2D or 3D fix (M = manual)
+     *  2) 3D fix - values include: 1 = no fix, 2 = 2D, 3 = 2D
+     *  3) PRNs of satellites used for fix
+     *     (space for 12)
+     *  4) PDOP (dilution of precision)
+     *  5) Horizontal dilution of precision (HDOP)
+     *  6) Vertical dilution of precision (VDOP)
+     *  7) Checksum
+     */
+    gchar *token;
+    gint i;
+    vprintf("%s(): %s\n", __PRETTY_FUNCTION__, sentence);
+
+#define DELIM ","
+
+    /* Skip Auto selection. */
+    token = strsep(&sentence, DELIM);
+
+    /* 3D fix. */
+    token = strsep(&sentence, DELIM);
+    if(token && *token)
+        MACRO_PARSE_INT(_gps.fix, token);
+
+    _gps.satinuse = 0;
+    for(i = 0; i < 12; i++)
+    {
+        token = strsep(&sentence, DELIM);
+        if(token && *token)
+            _gps.satforfix[_gps.satinuse++] = atoi(token);
+    }
+
+    /* PDOP */
+    token = strsep(&sentence, DELIM);
+    if(token && *token)
+        MACRO_PARSE_FLOAT(_gps.pdop, token);
+
+    /* HDOP */
+    token = strsep(&sentence, DELIM);
+    if(token && *token)
+        MACRO_PARSE_FLOAT(_gps.hdop, token);
+
+    /* VDOP */
+    token = strsep(&sentence, DELIM);
+    if(token && *token)
+        MACRO_PARSE_FLOAT(_gps.vdop, token);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+static void
+gps_parse_gsv(gchar *sentence)
+{
+    /* Must be GSV - Satellites in view
+     *  1) total number of messages
+     *  2) message number
+     *  3) satellites in view
+     *  4) satellite number
+     *  5) elevation in degrees (0-90)
+     *  6) azimuth in degrees to true north (0-359)
+     *  7) SNR in dB (0-99)
+     *  more satellite infos like 4)-7)
+     *  n) checksum
+     */
+    gchar *token;
+    gint msgcnt = 0, nummsgs = 0;
+    static gint running_total = 0;
+    static gint num_sats_used = 0;
+    static gint satcnt = 0;
+    vprintf("%s(): %s\n", __PRETTY_FUNCTION__, sentence);
+
+    /* Parse number of messages. */
+    token = strsep(&sentence, DELIM);
+    if(token && *token)
+        MACRO_PARSE_INT(nummsgs, token);
+
+    /* Parse message number. */
+    token = strsep(&sentence, DELIM);
+    if(token && *token)
+        MACRO_PARSE_INT(msgcnt, token);
+
+    /* Parse number of satellites in view. */
+    token = strsep(&sentence, DELIM);
+    if(token && *token)
+    {
+        MACRO_PARSE_INT(_gps.satinview, token);
+        if(_gps.satinview > 12) /* Handle buggy NMEA. */
+            _gps.satinview = 12;
+    }
+
+    /* Loop until there are no more satellites to parse. */
+    while(sentence && satcnt < 12)
+    {
+        /* Get token for Satellite Number. */
+        token = strsep(&sentence, DELIM);
+        if(token && *token)
+            _gps_sat[satcnt].prn = atoi(token);
+
+        /* Get token for elevation in degrees (0-90). */
+        token = strsep(&sentence, DELIM);
+        if(token && *token)
+            _gps_sat[satcnt].elevation = atoi(token);
+
+        /* Get token for azimuth in degrees to true north (0-359). */
+        token = strsep(&sentence, DELIM);
+        if(token && *token)
+            _gps_sat[satcnt].azimuth = atoi(token);
+
+        /* Get token for SNR. */
+        token = strsep(&sentence, DELIM);
+        if(token && *token && (_gps_sat[satcnt].snr = atoi(token)))
+        {
+            /* SNR is non-zero - add to total and count as used. */
+            running_total += _gps_sat[satcnt].snr;
+            num_sats_used++;
+        }
+        satcnt++;
+    }
+
+    if(msgcnt == nummsgs)
+    {
+        /*  This is the last message. Calculate signal strength. */
+        if(num_sats_used)
+        {
+            if(_gps_state == RCVR_UP)
+            {
+                gdouble fraction = running_total * sqrtf(num_sats_used)
+                    / num_sats_used / 100.0;
+                BOUND(fraction, 0.0, 1.0);
+                hildon_banner_set_fraction(
+                        HILDON_BANNER(_fix_banner), fraction);
+            }
+            running_total = 0;
+            num_sats_used = 0;
+        }
+        satcnt = 0;
+
+        /* Keep awake while they watch the progress bar. */
+        UNBLANK_SCREEN(TRUE, FALSE);
+    }
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+void
+gps_init()
+{
+    DBusGConnection *dbus_conn;
+    GError *error = NULL;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    _gps_init_mutex = g_mutex_new();
+
+    /* Initialize D-Bus. */
+    if(NULL == (dbus_conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error)))
+    {
+        g_printerr("Failed to open connection to D-Bus: %s.\n",
+                error->message);
+        error = NULL;
+    }
+
+    if(NULL == (_rfcomm_req_proxy = dbus_g_proxy_new_for_name(
+                    dbus_conn,
+                    BTCOND_SERVICE,
+                    BTCOND_REQ_PATH,
+                    BTCOND_REQ_INTERFACE)))
+    {
+        g_printerr("Failed to open connection to %s.\n",
+                BTCOND_REQ_INTERFACE);
+    }
+
+    /* set _gpsoffset */
+    {   
+        time_t time1;
+        struct tm time2;
+        time1 = time(NULL);
+        localtime_r(&time1, &time2);
+        _gmtoffset = time2.tm_gmtoff;
+    }
+
+    vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+}
+static gboolean
+gps_handle_error_idle(gchar *error)
+{
+    printf("%s(%s)\n", __PRETTY_FUNCTION__, error);
+
+    /* Ask for re-try. */
+    if(++_gps_rcvr_retry_count > 2)
+    {
+        GtkWidget *confirm;
+        gchar buffer[BUFFER_SIZE];
+
+        snprintf(buffer, sizeof(buffer), "%s\nRetry?", error);
+        confirm = hildon_note_new_confirmation(GTK_WINDOW(_window), buffer);
+
+        rcvr_disconnect();
+
+        if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm)))
+            rcvr_connect(); /* Try again. */
+        else
+        {
+            /* Disable GPS. */
+            gtk_check_menu_item_set_active(
+                    GTK_CHECK_MENU_ITEM(_menu_enable_gps_item), FALSE);
+        }
+
+        /* Ask user to re-connect. */
+        gtk_widget_destroy(confirm);
+    }
+    else
+    {
+        rcvr_disconnect();
+        rcvr_connect(); /* Try again. */
+    }
+
+    g_free(error);
+
+    vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+    return FALSE;
+}
+
+static gboolean
+gps_update_state_idle(gpointer data)
+{
+    ConnState new_state = GPOINTER_TO_INT(data);
+    printf("%s(%d)\n", __PRETTY_FUNCTION__, new_state);
+
+    if(new_state < RCVR_FIXED)
+    {
+        if(_track.tail->unity)
+            track_insert_break(FALSE);
+        _speed_excess = FALSE;
+    }
+    set_conn_state(new_state);
+
+    vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+    return FALSE;
+}
+
+static gboolean
+gps_parse_nmea_idle(gchar *nmea)
+{
+    printf("%s(%s)\n", __PRETTY_FUNCTION__, nmea);
+
+    if(_enable_gps && _gps_state > RCVR_DOWN)
+    {
+        if(!strncmp(nmea + 3, "GSV", 3))
+        {
+            if(_gps_state == RCVR_UP || _gps_info || _satdetails_on)
+                gps_parse_gsv(nmea + 7);
+        }
+        else if(!strncmp(nmea + 3, "RMC", 3))
+            gps_parse_rmc(nmea + 7);
+        else if(!strncmp(nmea + 3, "GGA", 3))
+            gps_parse_gga(nmea + 7);
+        else if(!strncmp(nmea + 3, "GSA", 3))
+            gps_parse_gsa(nmea + 7);
+
+        if(_gps_info)
+            gps_display_data();
+        if(_satdetails_on)
+            gps_display_details();
+    }
+
+    vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+    return FALSE;
+}
+
+static GpsRcvrInfo*
+gri_clone(GpsRcvrInfo *gri)
+{
+    GpsRcvrInfo *ret = g_new(GpsRcvrInfo, 1);
+    ret->type = gri->type;
+    ret->bt_mac = g_strdup(gri->bt_mac);
+    ret->bt_file = g_strdup(gri->bt_file);
+    ret->file_path = g_strdup(gri->file_path);
+    ret->gpsd_host = g_strdup(gri->gpsd_host);
+    ret->gpsd_port = gri->gpsd_port;
+    return ret;
+}
+
+static void
+gri_free(GpsRcvrInfo *gri)
+{
+    g_free(gri->bt_mac);
+    g_free(gri->file_path);
+    g_free(gri->gpsd_host);
+    g_free(gri);
+}
+
+static void
+thread_read_nmea(GpsRcvrInfo *gri)
+{
+    gchar buf[GPS_READ_BUF_SIZE];
+    gchar *buf_curr = buf;
+    gchar *buf_last = buf + GPS_READ_BUF_SIZE - 1;
+    GnomeVFSFileSize bytes_read;
+    GnomeVFSHandle *handle = NULL;
+    GnomeVFSInetConnection *iconn = NULL;
+    GnomeVFSSocket *socket = NULL;
+    GnomeVFSResult vfs_result;
+    GThread *my_thread = g_thread_self();
+    gboolean error = FALSE;
+    printf("%s(%d)\n", __PRETTY_FUNCTION__, gri->type);
+
+    /* Lock/Unlock the mutex to ensure that _gps_thread is done being set. */
+    g_mutex_lock(_gps_init_mutex);
+    g_mutex_unlock(_gps_init_mutex);
+
+    if(gri->type == GPS_RCVR_GPSD)
+    {
+        /* Create a socket to interact with GPSD. */
+        GTimeVal timeout = { 15, 0 };
+        vfs_result = gnome_vfs_inet_connection_create(&iconn,
+                gri->gpsd_host, gri->gpsd_port, NULL);
+        if(vfs_result != GNOME_VFS_OK
+               || NULL == (socket = gnome_vfs_inet_connection_to_socket(iconn))
+               || GNOME_VFS_OK != (vfs_result = gnome_vfs_socket_set_timeout(
+                       socket, &timeout, NULL))
+               || GNOME_VFS_OK != (vfs_result = gnome_vfs_socket_write(socket,
+                       "r\r\n", sizeof("r\r\n"), &bytes_read, NULL))
+               || bytes_read != sizeof("r\r\n"))
+        {
+            g_idle_add((GSourceFunc)gps_handle_error_idle,
+                    g_strdup_printf("%s",
+                    _("Error connecting to GPSD.")));
+            error = TRUE;
+        }
+    }
+    else
+    {
+        /* Open a handle to interact with a file. */
+        vfs_result = gnome_vfs_open(&handle,
+                gri->type == GPS_RCVR_BT ? gri->bt_file : gri->file_path,
+                GNOME_VFS_OPEN_READ);
+        if(vfs_result != GNOME_VFS_OK)
+        {
+            g_idle_add((GSourceFunc)gps_handle_error_idle,
+                    g_strdup_printf("%s",
+                    _("Error connecting to GPS receiver.")));
+            error = TRUE;
+        }
+    }
+
+    if(vfs_result == GNOME_VFS_OK)
+    {
+        g_idle_add((GSourceFunc)gps_update_state_idle, (void*)RCVR_UP);
+        while(my_thread == _gps_thread)
+        {
+            gchar *eol;
+            if(gri->type == GPS_RCVR_GPSD)
+            {
+                vfs_result = gnome_vfs_socket_read( 
+                        socket,
+                        buf,
+                        buf_last - buf_curr,
+                        &bytes_read,
+                        NULL);
+            }
+            else
+            {
+                vfs_result = gnome_vfs_read( 
+                        handle,
+                        buf,
+                        buf_last - buf_curr,
+                        &bytes_read);
+            }
+
+            if(vfs_result != GNOME_VFS_OK)
+            {
+                if(my_thread == _gps_thread)
+                {
+                    /* Error wasn't user-initiated. */
+                    g_idle_add((GSourceFunc)gps_handle_error_idle,
+                            g_strdup_printf("%s",
+                                _("Error reading GPS data.")));
+                    error = TRUE;
+                }
+                break;
+            }
+
+            /* Successful connection.  Reset the retry counter. */
+            _gps_rcvr_retry_count = 0;
+
+            buf_curr += bytes_read;
+            *buf_curr = '\0'; /* append a \0 so we can read as string */
+            while(my_thread == _gps_thread && (eol = strchr(buf, '\n')))
+            {
+                gint csum = 0;
+                if(*buf == '$')
+                {
+                    gchar *sptr = buf + 1; /* Skip the $ */
+                    /* This is the beginning of a sentence; okay to parse. */
+                    *eol = '\0'; /* overwrite \n with \0 */
+                    while(*sptr && *sptr != '*')
+                        csum ^= *sptr++;
+
+                    /* If we're at a \0 (meaning there is no checksum), or if
+                     * the checksum is good, then parse the sentence. */
+                    if(!*sptr || csum == strtol(sptr + 1, NULL, 16))
+                    {
+                        if(*sptr)
+                            *sptr = '\0'; /* take checksum out of the buffer.*/
+                        if(my_thread == _gps_thread)
+                            g_idle_add((GSourceFunc)gps_parse_nmea_idle,
+                                    g_strdup(buf));
+                    }
+                    else
+                    {
+                        /* There was a checksum, and it was bad. */
+                        g_printerr("%s: Bad checksum in NMEA sentence:\n%s\n",
+                                __PRETTY_FUNCTION__, buf);
+                    }
+                }
+
+                /* If eol is at or after (buf_curr - 1) */
+                if(eol >= (buf_curr - 1))
+                {
+                    /* Last read was a newline - reset read buffer */
+                    buf_curr = buf;
+                    *buf_curr = '\0';
+                }
+                else
+                {
+                    /* Move the next line to the front of the buffer. */
+                    memmove(buf, eol + 1,
+                            buf_curr - eol); /* include terminating 0 */
+                    /* Subtract _curr so that it's pointing at the new \0. */
+                    buf_curr -= (eol - buf + 1);
+                }
+            }
+        }
+    }
+
+    /* Clean up. */
+    if(handle)
+        gnome_vfs_close(handle);
+    if(iconn)
+        gnome_vfs_inet_connection_free(iconn, NULL);
+
+    if(!error)
+    {
+        g_idle_add((GSourceFunc)gps_update_state_idle,
+                GINT_TO_POINTER(RCVR_OFF));
+    }
+    gri_free(gri);
+
+    printf("%s(): g_thread_exit(NULL)\n", __PRETTY_FUNCTION__);
+    g_thread_exit(NULL);
+}
+
+/**
+ * Set the connection state.  This function controls all connection-related
+ * banners.
+ */
+void
+set_conn_state(ConnState new_conn_state)
+{
+    printf("%s(%d)\n", __PRETTY_FUNCTION__, new_conn_state);
+
+    switch(_gps_state = new_conn_state)
+    {
+        case RCVR_OFF:
+        case RCVR_FIXED:
+            if(_connect_banner)
+            {
+                gtk_widget_destroy(_connect_banner);
+                _connect_banner = NULL;
+            }
+            if(_fix_banner)
+            {
+                gtk_widget_destroy(_fix_banner);
+                _fix_banner = NULL;
+            }
+            break;
+        case RCVR_DISCONNECT:
+            if(_connect_banner)
+            {
+                gtk_widget_destroy(_connect_banner);
+                _connect_banner = NULL;
+            }
+            if(_fix_banner)
+            {
+                gtk_widget_destroy(_fix_banner);
+                _fix_banner = NULL;
+            }
+            _connect_banner = hildon_banner_show_animation(
+                    _window, NULL, _("Disconnecting from GPS receiver"));
+            break;
+
+        case RCVR_DOWN:
+            if(_fix_banner)
+            {
+                gtk_widget_destroy(_fix_banner);
+                _fix_banner = NULL;
+            }
+            if(!_connect_banner)
+                _connect_banner = hildon_banner_show_animation(
+                        _window, NULL, _("Searching for GPS receiver"));
+            break;
+        case RCVR_UP:
+            if(_connect_banner)
+            {
+                gtk_widget_destroy(_connect_banner);
+                _connect_banner = NULL;
+            }
+            if(!_fix_banner)
+            {
+                _fix_banner = hildon_banner_show_progress(
+                        _window, NULL, _("Establishing GPS fix"));
+            }
+            break;
+        default: ; /* to quell warning. */
+    }
+    map_force_redraw();
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+/**
+ * Disconnect from the receiver.  This method cleans up any and everything
+ * that might be associated with the receiver.
+ */
+void
+rcvr_disconnect()
+{
+    GError *error = NULL;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(_gps_thread)
+        set_conn_state(RCVR_DISCONNECT);
+
+    _gps_thread = NULL;
+
+    /* Check if we need to cancel the RFComm request. */
+    if(!_gps_thread && _gri.type == GPS_RCVR_BT && _rfcomm_req_proxy)
+    {
+        dbus_g_proxy_call(_rfcomm_req_proxy, BTCOND_RFCOMM_CANCEL_CONNECT_REQ,
+                    &error,
+                    G_TYPE_STRING, _gri.bt_mac,
+                    G_TYPE_STRING, "SPP",
+                    G_TYPE_INVALID,
+                    G_TYPE_INVALID);
+        error = NULL;
+        dbus_g_proxy_call(_rfcomm_req_proxy, BTCOND_RFCOMM_DISCONNECT_REQ,
+                    &error,
+                    G_TYPE_STRING, _gri.bt_mac,
+                    G_TYPE_STRING, "SPP",
+                    G_TYPE_INVALID,
+                    G_TYPE_INVALID);
+        set_conn_state(RCVR_OFF);
+    }
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+/**
+ * Connect to the receiver.
+ * This method assumes that _fd is -1 and _channel is NULL.  If unsure, call
+ * rcvr_disconnect() first.
+ * Since this is an idle function, this function returns whether or not it
+ * should be called again, which is always FALSE.
+ */
+gboolean
+rcvr_connect()
+{
+    printf("%s(%d)\n", __PRETTY_FUNCTION__, _gps_state);
+
+    if(_enable_gps && _gps_state <= RCVR_DISCONNECT
+            && _gri.type != GPS_RCVR_NONE)
+    {
+        set_conn_state(RCVR_DOWN);
+
+        if(_gri.type != GPS_RCVR_BT || (_gri.bt_file &&
+                    g_file_test(_gri.bt_file, G_FILE_TEST_EXISTS)))
+        {
+            /* Lock/Unlock the mutex to ensure that the thread doesn't
+             * start until _gps_thread is set. */
+            g_mutex_lock(_gps_init_mutex);
+            _gps_thread = g_thread_create((GThreadFunc)thread_read_nmea,
+                    gri_clone(&_gri), FALSE, NULL);
+            g_mutex_unlock(_gps_init_mutex);
+        }
+        else
+        {
+            /* Create the RFCOMM file descriptor. */
+            if(_rfcomm_req_proxy)
+            {
+                gint mybool = TRUE;
+                dbus_g_proxy_begin_call(
+                        _rfcomm_req_proxy, BTCOND_RFCOMM_CONNECT_REQ,
+                        (DBusGProxyCallNotify)rcvr_connect_response,
+                        NULL, NULL,
+                        G_TYPE_STRING, _gri.bt_mac,
+                        G_TYPE_STRING, "SPP",
+                        G_TYPE_BOOLEAN, &mybool,
+                        G_TYPE_INVALID);
+            }
+        }
+    }
+
+    vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+    return FALSE;
+}
+
+static void
+rcvr_connect_response(DBusGProxy *proxy, DBusGProxyCall *call_id)
+{
+    GError *error = NULL;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if((_gps_state == RCVR_DOWN || _gps_state == RCVR_DISCONNECT)
+        && _gri.type != GPS_RCVR_NONE)
+    {
+        if(!dbus_g_proxy_end_call(_rfcomm_req_proxy, call_id, &error,
+                    G_TYPE_STRING, &_gri.bt_file, G_TYPE_INVALID))
+        {
+            if(error->domain == DBUS_GERROR
+                    && error->code == DBUS_GERROR_REMOTE_EXCEPTION)
+            {
+                /* If we're already connected, it's not an error, unless
+                 * they don't give us the file descriptor path, in which
+                 * case we re-connect.*/
+                if(!strcmp(BTCOND_ERROR_CONNECTED,
+                            dbus_g_error_get_name(error)) || !_gri.bt_file)
+                {
+                    printf("Caught remote method exception %s: %s",
+                            dbus_g_error_get_name(error),
+                            error->message);
+
+                    gps_handle_error_idle(
+                            _("Failed to connect to Bluetooth GPS receiver."));
+                    return;
+                }
+            }
+            else
+            {
+                /* Unknown error. */
+                g_printerr("Error: %s\n", error->message);
+                rcvr_disconnect();
+                rcvr_connect(); /* Try again. */
+                return;
+            }
+        }
+        /* Lock/Unlock the mutex to ensure that the thread doesn't
+         * start until _gps_thread is set. */
+        g_mutex_lock(_gps_init_mutex);
+        _gps_thread = g_thread_create((GThreadFunc)thread_read_nmea,
+                gri_clone(&_gri), FALSE, NULL);
+        g_mutex_unlock(_gps_init_mutex);
+    }
+    /* else { Looks like the middle of a disconnect.  Do nothing. } */
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+void
+reset_bluetooth()
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+    if(system("/usr/bin/sudo -l | grep -q '/usr/sbin/hciconfig  *hci0  *reset'"
+            " && sudo /usr/sbin/hciconfig hci0 reset"))
+        popup_error(_window,
+                _("An error occurred while trying to reset the bluetooth "
+                "radio.\n\n"
+                "Did you make sure to modify\nthe /etc/sudoers file?"));
+    else if(_gps_state > RCVR_DISCONNECT)
+    {
+        rcvr_connect();
+    }
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
diff --git a/src/gps.h b/src/gps.h
new file mode 100644 (file)
index 0000000..5c3e415
--- /dev/null
+++ b/src/gps.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAEMO_MAPPER_GPS_H
+#define MAEMO_MAPPER_GPS_H
+
+void set_conn_state(ConnState new_conn_state);
+
+gboolean rcvr_connect();
+void rcvr_disconnect();
+
+void reset_bluetooth();
+
+void gps_init();
+
+#endif /* ifndef MAEMO_MAPPER_GPS_H */
diff --git a/src/gpx.c b/src/gpx.c
new file mode 100644 (file)
index 0000000..6f75d75
--- /dev/null
+++ b/src/gpx.c
@@ -0,0 +1,902 @@
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define _GNU_SOURCE
+
+#include <string.h>
+#include <math.h>
+#include <libxml/parser.h>
+
+#include "types.h"
+#include "data.h"
+#include "defines.h"
+
+#include "gpx.h"
+#include "path.h"
+#include "util.h"
+
+/**
+ * Handle a start tag in the parsing of a GPX file.
+ */
+#define MACRO_SET_UNKNOWN() { \
+    data->sax_data.prev_state = data->sax_data.state; \
+    data->sax_data.state = UNKNOWN; \
+    data->sax_data.unknown_depth = 1; \
+}
+
+static gchar XML_TZONE[7];
+
+/**
+ * Handle char data in the parsing of a GPX file.
+ */
+static void
+gpx_chars(SaxData *data, const xmlChar *ch, int len)
+{
+    gint i;
+    vprintf("%s()\n", __PRETTY_FUNCTION__);
+
+    switch(data->state)
+    {
+        case ERROR:
+        case UNKNOWN:
+            break;
+        case INSIDE_WPT_NAME:
+        case INSIDE_WPT_DESC:
+        case INSIDE_PATH_POINT_ELE:
+        case INSIDE_PATH_POINT_TIME:
+        case INSIDE_PATH_POINT_DESC:
+            for(i = 0; i < len; i++)
+                data->chars = g_string_append_c(data->chars, ch[i]);
+            vprintf("%s\n", data->chars->str);
+            break;
+        default:
+            break;
+    }
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+/**
+ * Handle an entity in the parsing of a GPX file.  We don't do anything
+ * special here.
+ */
+static xmlEntityPtr
+gpx_get_entity(SaxData *data, const xmlChar *name)
+{
+    vprintf("%s()\n", __PRETTY_FUNCTION__);
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+    return xmlGetPredefinedEntity(name);
+}
+
+/**
+ * Handle an error in the parsing of a GPX file.
+ */
+static void
+gpx_error(SaxData *data, const gchar *msg, ...)
+{
+    vprintf("%s()\n", __PRETTY_FUNCTION__);
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+    data->state = ERROR;
+}
+
+/****************************************************************************
+ * BELOW: OPEN PATH *********************************************************
+ ****************************************************************************/
+
+static void
+gpx_path_start_element(PathSaxData *data,
+        const xmlChar *name, const xmlChar **attrs)
+{
+    vprintf("%s(%s)\n", __PRETTY_FUNCTION__, name);
+
+    switch(data->sax_data.state)
+    {
+        case ERROR:
+            printf("ERROR!\n");
+            break;
+        case START:
+            if(!strcmp((gchar*)name, "gpx"))
+                data->sax_data.state = INSIDE_GPX;
+            else
+                MACRO_SET_UNKNOWN();
+            break;
+        case INSIDE_GPX:
+            if(!strcmp((gchar*)name, "trk"))
+                data->sax_data.state = INSIDE_PATH;
+            else
+                MACRO_SET_UNKNOWN();
+            break;
+        case INSIDE_PATH:
+            if(!strcmp((gchar*)name, "trkseg"))
+            {
+                data->sax_data.state = INSIDE_PATH_SEGMENT;
+                data->sax_data.at_least_one_trkpt = FALSE;
+            }
+            else
+                MACRO_SET_UNKNOWN();
+            break;
+        case INSIDE_PATH_SEGMENT:
+            if(!strcmp((gchar*)name, "trkpt"))
+            {
+                const xmlChar **curr_attr;
+                gchar *error_check;
+                gfloat lat = 0.f, lon = 0.f;
+                gboolean has_lat, has_lon;
+                has_lat = FALSE;
+                has_lon = FALSE;
+                for(curr_attr = attrs; *curr_attr != NULL; )
+                {
+                    const gchar *attr_name = *curr_attr++;
+                    const gchar *attr_val = *curr_attr++;
+                    if(!strcmp(attr_name, "lat"))
+                    {
+                        lat = g_ascii_strtod(attr_val, &error_check);
+                        if(error_check != attr_val)
+                            has_lat = TRUE;
+                    }
+                    else if(!strcmp(attr_name, "lon"))
+                    {
+                        lon = g_ascii_strtod(attr_val, &error_check);
+                        if(error_check != attr_val)
+                            has_lon = TRUE;
+                    }
+                }
+                if(has_lat && has_lon)
+                {
+                    MACRO_PATH_INCREMENT_TAIL(data->path);
+                    latlon2unit(lat, lon,
+                            data->path.tail->unitx,
+                            data->path.tail->unity);
+                    data->path.tail->time = 0;
+                    data->path.tail->altitude = 0;
+                    data->sax_data.state = INSIDE_PATH_POINT;
+                }
+                else
+                    data->sax_data.state = ERROR;
+            }
+            else
+                MACRO_SET_UNKNOWN();
+            break;
+        case INSIDE_PATH_POINT:
+            if(!strcmp((gchar*)name, "time"))
+                data->sax_data.state = INSIDE_PATH_POINT_TIME;
+            else if(!strcmp((gchar*)name, "ele"))
+                data->sax_data.state = INSIDE_PATH_POINT_ELE;
+            else if(!strcmp((gchar*)name, "desc"))
+                data->sax_data.state = INSIDE_PATH_POINT_DESC;
+
+            else
+                MACRO_SET_UNKNOWN();
+            break;
+        case UNKNOWN:
+            data->sax_data.unknown_depth++;
+            break;
+        default:
+            ;
+    }
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+/**
+ * Handle an end tag in the parsing of a GPX file.
+ */
+static void
+gpx_path_end_element(PathSaxData *data, const xmlChar *name)
+{
+    vprintf("%s(%s)\n", __PRETTY_FUNCTION__, name);
+
+    switch(data->sax_data.state)
+    {
+        case ERROR:
+            printf("ERROR!\n");
+            break;
+        case START:
+            data->sax_data.state = ERROR;
+            break;
+        case INSIDE_GPX:
+            if(!strcmp((gchar*)name, "gpx"))
+                data->sax_data.state = FINISH;
+            else
+                data->sax_data.state = ERROR;
+            break;
+        case INSIDE_PATH:
+            if(!strcmp((gchar*)name, "trk"))
+                data->sax_data.state = INSIDE_GPX;
+            else
+                data->sax_data.state = ERROR;
+            break;
+        case INSIDE_PATH_SEGMENT:
+            if(!strcmp((gchar*)name, "trkseg"))
+            {
+                if(data->sax_data.at_least_one_trkpt)
+                {
+                    MACRO_PATH_INCREMENT_TAIL(data->path);
+                    *data->path.tail = _point_null;
+                }
+                data->sax_data.state = INSIDE_PATH;
+            }
+            else
+                data->sax_data.state = ERROR;
+            break;
+        case INSIDE_PATH_POINT:
+            if(!strcmp((gchar*)name, "trkpt"))
+            {
+                data->sax_data.state = INSIDE_PATH_SEGMENT;
+                data->sax_data.at_least_one_trkpt = TRUE;
+            }
+            else
+                data->sax_data.state = ERROR;
+            break;
+        case INSIDE_PATH_POINT_ELE:
+            if(!strcmp((gchar*)name, "ele"))
+            {
+                gchar *error_check;
+                data->path.tail->altitude
+                    = g_ascii_strtod(data->sax_data.chars->str, &error_check);
+                if(error_check == data->sax_data.chars->str)
+                    data->path.tail->altitude = 0;
+                data->sax_data.state = INSIDE_PATH_POINT;
+                g_string_free(data->sax_data.chars, TRUE);
+                data->sax_data.chars = g_string_new("");
+            }
+            else
+                data->sax_data.state = ERROR;
+            break;
+        case INSIDE_PATH_POINT_TIME:
+            if(!strcmp((gchar*)name, "time"))
+            {
+                struct tm time;
+                gchar *ptr;
+
+                if(NULL == (ptr = strptime(data->sax_data.chars->str,
+                            XML_DATE_FORMAT, &time)))
+                    /* Failed to parse dateTime format. */
+                    data->sax_data.state = ERROR;
+                else
+                {
+                    /* Parse was successful. Now we have to parse timezone.
+                     * From here on, if there is an error, I just assume local
+                     * timezone.  Yes, this is not proper XML, but I don't
+                     * care. */
+                    gchar *error_check;
+
+                    /* First, set time in "local" time zone. */
+                    data->path.tail->time = (mktime(&time));
+
+                    /* Now, skip inconsequential characters */
+                    while(*ptr && *ptr != 'Z' && *ptr != '-' && *ptr != '+')
+                        ptr++;
+
+                    /* Check if we ran to the end of the string. */
+                    if(*ptr)
+                    {
+                        /* Next character is either 'Z', '-', or '+' */
+                        if(*ptr == 'Z')
+                            /* Zulu (UTC) time. Undo the local time zone's
+                             * offset. */
+                            data->path.tail->time += time.tm_gmtoff;
+                        else
+                        {
+                            /* Not Zulu (UTC). Must parse hours and minutes. */
+                            gint offhours = strtol(ptr, &error_check, 10);
+                            if(error_check != ptr
+                                    && *(ptr = error_check) == ':')
+                            {
+                                /* Parse of hours worked. Check minutes. */
+                                gint offmins = strtol(ptr + 1,
+                                        &error_check, 10);
+                                if(error_check != (ptr + 1))
+                                {
+                                    /* Parse of minutes worked. Calculate. */
+                                    data->path.tail->time
+                                        += (time.tm_gmtoff
+                                                - (offhours * 60 * 60
+                                                    + offmins * 60));
+                                }
+                            }
+                        }
+                    }
+                    /* Successfully parsed dateTime. */
+                    data->sax_data.state = INSIDE_PATH_POINT;
+                }
+
+                g_string_free(data->sax_data.chars, TRUE);
+                data->sax_data.chars = g_string_new("");
+            }
+            else
+                data->sax_data.state = ERROR;
+            break;
+        case INSIDE_PATH_POINT_DESC:
+            /* only parse description for routes */
+            if(!strcmp((gchar*)name, "desc"))
+            {
+                MACRO_PATH_INCREMENT_WTAIL(data->path);
+                data->path.wtail->point = data->path.tail;
+                data->path.wtail->desc
+                    = g_string_free(data->sax_data.chars, FALSE);
+                data->sax_data.chars = g_string_new("");
+                data->sax_data.state = INSIDE_PATH_POINT;
+            }
+            else
+                data->sax_data.state = ERROR;
+            break;
+        case UNKNOWN:
+            if(!--data->sax_data.unknown_depth)
+                data->sax_data.state = data->sax_data.prev_state;
+            else
+                data->sax_data.state = ERROR;
+            break;
+        default:
+            ;
+    }
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+gboolean
+gpx_path_parse(Path *to_replace, gchar *buffer, gint size, gint policy_old)
+{
+    PathSaxData data;
+    xmlSAXHandler sax_handler;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    MACRO_PATH_INIT(data.path);
+    data.sax_data.state = START;
+    data.sax_data.chars = g_string_new("");
+
+    memset(&sax_handler, 0, sizeof(sax_handler));
+    sax_handler.characters = (charactersSAXFunc)gpx_chars;
+    sax_handler.startElement = (startElementSAXFunc)gpx_path_start_element;
+    sax_handler.endElement = (endElementSAXFunc)gpx_path_end_element;
+    sax_handler.entityDecl = (entityDeclSAXFunc)gpx_get_entity;
+    sax_handler.warning = (warningSAXFunc)gpx_error;
+    sax_handler.error = (errorSAXFunc)gpx_error;
+    sax_handler.fatalError = (fatalErrorSAXFunc)gpx_error;
+
+    xmlSAXUserParseMemory(&sax_handler, &data.sax_data, buffer, size);
+    g_string_free(data.sax_data.chars, TRUE);
+
+    if(data.sax_data.state != FINISH)
+    {
+        vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+        return FALSE;
+    }
+
+    if(policy_old && to_replace->head != to_replace->tail)
+    {
+        Point *src_first;
+        Path *src, *dest;
+
+        if(policy_old > 0)
+        {
+            /* Append to current path. Make sure last path point is zero. */
+            if(to_replace->tail->unity != 0)
+            {
+                MACRO_PATH_INCREMENT_TAIL((*to_replace));
+                *to_replace->tail = _point_null;
+            }
+            src = &data.path;
+            dest = to_replace;
+        }
+        else
+        {
+            /* Prepend to current route. */
+            src = to_replace;
+            dest = &data.path;
+        }
+
+        /* Find src_first non-zero point. */
+        for(src_first = src->head - 1; src_first++ != src->tail; )
+            if(src_first->unity)
+                break;
+
+        /* Append route points from src to dest. */
+        if(src->tail >= src_first)
+        {
+            WayPoint *curr;
+            gint num_dest_points = dest->tail - dest->head + 1;
+            gint num_src_points = src->tail - src_first + 1;
+
+            /* Adjust dest->tail to be able to fit src route data
+             * plus room for more route data. */
+            path_resize(dest, num_dest_points + num_src_points);
+
+            memcpy(dest->tail + 1, src_first,
+                    num_src_points * sizeof(Point));
+
+            dest->tail += num_src_points;
+
+            /* Append waypoints from src to dest->. */
+            path_wresize(dest, (dest->wtail - dest->whead)
+                    + (src->wtail - src->whead) + 2);
+            for(curr = src->whead - 1; curr++ != src->wtail; )
+            {
+                (++(dest->wtail))->point = dest->head + num_dest_points
+                    + (curr->point - src_first);
+                dest->wtail->desc = curr->desc;
+            }
+
+        }
+
+        /* Kill old route - don't use MACRO_PATH_FREE(), because that
+         * would free the string desc's that we just moved to data.route. */
+        g_free(src->head);
+        g_free(src->whead);
+        if(policy_old < 0)
+            (*to_replace) = *dest;
+    }
+    else
+    {
+        MACRO_PATH_FREE((*to_replace));
+        /* Overwrite with data.route. */
+        (*to_replace) = data.path;
+        path_resize(to_replace, to_replace->tail - to_replace->head + 1);
+        path_wresize(to_replace, to_replace->wtail - to_replace->whead + 1);
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+/****************************************************************************
+ * ABOVE: OPEN PATH *********************************************************
+ ****************************************************************************/
+
+/****************************************************************************
+ * BELOW: SAVE PATH *********************************************************
+ ****************************************************************************/
+
+#define WRITE_STRING(string) { \
+    GnomeVFSResult vfs_result; \
+    GnomeVFSFileSize size; \
+    if(GNOME_VFS_OK != (vfs_result = gnome_vfs_write( \
+                    handle, (string), strlen((string)), &size))) \
+    { \
+        gchar buffer[BUFFER_SIZE]; \
+        snprintf(buffer, sizeof(buffer), \
+                "%s:\n%s\n%s", _("Error while writing to file"), \
+                _("File is incomplete."), \
+                gnome_vfs_result_to_string(vfs_result)); \
+        popup_error(_window, buffer); \
+        return FALSE; \
+    } \
+}
+
+gboolean
+gpx_path_write(Path *path, GnomeVFSHandle *handle)
+{
+    Point *curr = NULL;
+    WayPoint *wcurr = NULL;
+    gboolean trkseg_break = FALSE;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    /* Find first non-zero point. */
+    for(curr = path->head - 1, wcurr = path->whead; curr++ != path->tail; )
+    {
+        if(curr->unity)
+            break;
+        else if(wcurr <= path->wtail && curr == wcurr->point)
+            wcurr++;
+    }
+
+    /* Write the header. */
+    WRITE_STRING(
+            "<?xml version=\"1.0\"?>\n"
+            "<gpx version=\"1.0\" creator=\"maemo-mapper\" "
+            "xmlns=\"http://www.topografix.com/GPX/1/0\">\n"
+            "  <trk>\n"
+            "    <trkseg>\n");
+
+    /* Curr points to first non-zero point. */
+    for(curr--; curr++ != path->tail; )
+    {
+        gfloat lat, lon;
+        if(curr->unity)
+        {
+            gchar buffer[80];
+            gboolean first_sub = TRUE;
+            if(trkseg_break)
+            {
+                /* First trkpt of the segment - write trkseg header. */
+                WRITE_STRING("    </trkseg>\n"
+                             "    <trkseg>\n");
+                trkseg_break = FALSE;
+            }
+            unit2latlon(curr->unitx, curr->unity, lat, lon);
+            WRITE_STRING("      <trkpt lat=\"");
+            g_ascii_formatd(buffer, sizeof(buffer), "%.06f", lat);
+            WRITE_STRING(buffer);
+            WRITE_STRING("\" lon=\"");
+            g_ascii_formatd(buffer, sizeof(buffer), "%.06f", lon);
+            WRITE_STRING(buffer);
+            WRITE_STRING("\"");
+
+            /* write the elevation */
+            if(curr->altitude > INT_MIN)
+            {
+                if(first_sub)
+                {
+                    WRITE_STRING(">\n");
+                    first_sub = FALSE;
+                }
+                WRITE_STRING("        <ele>");
+                {
+                    g_ascii_formatd(buffer, 80, "%.2f", curr->altitude);
+                    WRITE_STRING(buffer);
+                }
+                WRITE_STRING("</ele>\n");
+            }
+
+            /* write the time */
+            if(curr->time)
+            {
+                if(first_sub)
+                {
+                    WRITE_STRING(">\n");
+                    first_sub = FALSE;
+                }
+                WRITE_STRING("        <time>");
+                strftime(buffer, 80, XML_DATE_FORMAT, localtime(&curr->time));
+                WRITE_STRING(buffer);
+                WRITE_STRING(XML_TZONE);
+                WRITE_STRING("</time>\n");
+            }
+
+            if(wcurr && curr == wcurr->point)
+            {
+                if(first_sub)
+                {
+                    WRITE_STRING(">\n");
+                    first_sub = FALSE;
+                }
+                WRITE_STRING("        <desc>");
+                WRITE_STRING(wcurr->desc);
+                WRITE_STRING("</desc>\n");
+                wcurr++;
+            }
+            if(first_sub)
+            {
+                WRITE_STRING("/>\n");
+            }
+            else
+            {
+                WRITE_STRING("      </trkpt>\n");
+            }
+        }
+        else
+            trkseg_break = TRUE;
+    }
+
+    /* Write the footer. */
+    WRITE_STRING(
+            "    </trkseg>\n"
+            "  </trk>\n"
+            "</gpx>\n");
+
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+/****************************************************************************
+ * ABOVE: SAVE PATH *********************************************************
+ ****************************************************************************/
+
+/****************************************************************************
+ * BELOW: OPEN POI **********************************************************
+ ****************************************************************************/
+
+static void
+gpx_poi_start_element(PoiSaxData *data,
+        const xmlChar *name, const xmlChar **attrs)
+{
+    vprintf("%s(%s)\n", __PRETTY_FUNCTION__, name);
+
+    switch(data->sax_data.state)
+    {
+        case ERROR:
+            printf("ERROR!\n");
+            break;
+        case START:
+            if(!strcmp((gchar*)name, "gpx"))
+                data->sax_data.state = INSIDE_GPX;
+            else
+                MACRO_SET_UNKNOWN();
+            break;
+        case INSIDE_GPX:
+            if(!strcmp((gchar*)name, "wpt"))
+            {
+                const xmlChar **curr_attr;
+                gchar *error_check;
+                gfloat lat = 0.f, lon = 0.f;
+                gboolean has_lat, has_lon;
+                has_lat = FALSE;
+                has_lon = FALSE;
+
+                /* Parse the attributes - there should be lat and lon. */
+                for(curr_attr = attrs; *curr_attr != NULL; )
+                {
+                    const gchar *attr_name = *curr_attr++;
+                    const gchar *attr_val = *curr_attr++;
+                    if(!strcmp(attr_name, "lat"))
+                    {
+                        lat = g_ascii_strtod(attr_val, &error_check);
+                        if(error_check != attr_val)
+                            has_lat = TRUE;
+                    }
+                    else if(!strcmp(attr_name, "lon"))
+                    {
+                        lon = g_ascii_strtod(attr_val, &error_check);
+                        if(error_check != attr_val)
+                            has_lon = TRUE;
+                    }
+                }
+                if(has_lat && has_lon)
+                {
+                    data->sax_data.state = INSIDE_WPT;
+                    data->curr_poi = g_slice_new0(PoiInfo);
+                    data->curr_poi->lat = lat;
+                    data->curr_poi->lon = lon;
+                    data->poi_list = g_list_append(
+                            data->poi_list, data->curr_poi);
+                }
+                else
+                    data->sax_data.state = ERROR;
+            }
+            else
+                MACRO_SET_UNKNOWN();
+            break;
+        case INSIDE_WPT:
+            if(!strcmp((gchar*)name, "name"))
+                data->sax_data.state = INSIDE_WPT_NAME;
+            else if(!strcmp((gchar*)name, "desc"))
+                data->sax_data.state = INSIDE_WPT_DESC;
+            else
+                MACRO_SET_UNKNOWN();
+            break;
+        case UNKNOWN:
+            printf("UNKNOWN!\n");
+            data->sax_data.unknown_depth++;
+            break;
+        default:
+            ;
+    }
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+/**
+ * Handle an end tag in the parsing of a GPX file.
+ */
+static void
+gpx_poi_end_element(PoiSaxData *data, const xmlChar *name)
+{
+    vprintf("%s(%s)\n", __PRETTY_FUNCTION__, name);
+
+    switch(data->sax_data.state)
+    {
+        case ERROR:
+            printf("ERROR!\n");
+            break;
+        case START:
+            data->sax_data.state = ERROR;
+            break;
+        case INSIDE_GPX:
+            if(!strcmp((gchar*)name, "gpx"))
+            {
+                data->sax_data.state = FINISH;
+            }
+            else
+                data->sax_data.state = ERROR;
+            break;
+        case INSIDE_WPT:
+            if(!strcmp((gchar*)name, "wpt"))
+                data->sax_data.state = INSIDE_GPX;
+            else
+                data->sax_data.state = ERROR;
+            break;
+        case INSIDE_WPT_NAME:
+            if(!strcmp((gchar*)name, "name"))
+            {
+                data->curr_poi->label
+                    = g_string_free(data->sax_data.chars, FALSE);
+                data->sax_data.chars = g_string_new("");
+                data->sax_data.state = INSIDE_WPT;
+            }
+            else
+                data->sax_data.state = ERROR;
+            break;
+        case INSIDE_WPT_DESC:
+            if(!strcmp((gchar*)name, "desc"))
+            {
+                data->curr_poi->desc
+                    = g_string_free(data->sax_data.chars, FALSE);
+                data->sax_data.chars = g_string_new("");
+                data->sax_data.state = INSIDE_WPT;
+            }
+            else
+                data->sax_data.state = ERROR;
+            break;
+        case UNKNOWN:
+            printf("UNKNOWN!\n");
+            if(!--data->sax_data.unknown_depth)
+                data->sax_data.state = data->sax_data.prev_state;
+            else
+                data->sax_data.state = ERROR;
+            break;
+        default:
+            ;
+    }
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+gboolean
+gpx_poi_parse(gchar *buffer, gint size, GList **poi_list)
+{
+    PoiSaxData sax_data;
+    xmlSAXHandler sax_handler;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    sax_data.poi_list = *poi_list;
+    sax_data.sax_data.state = START;
+    sax_data.sax_data.chars = g_string_new("");
+
+    memset(&sax_handler, 0, sizeof(sax_handler));
+    sax_handler.characters = (charactersSAXFunc)gpx_chars;
+    sax_handler.startElement = (startElementSAXFunc)gpx_poi_start_element;
+    sax_handler.endElement = (endElementSAXFunc)gpx_poi_end_element;
+    sax_handler.entityDecl = (entityDeclSAXFunc)gpx_get_entity;
+    sax_handler.warning = (warningSAXFunc)gpx_error;
+    sax_handler.error = (errorSAXFunc)gpx_error;
+    sax_handler.fatalError = (fatalErrorSAXFunc)gpx_error;
+
+    xmlSAXUserParseMemory(&sax_handler, &sax_data, buffer, size);
+    g_string_free(sax_data.sax_data.chars, TRUE);
+    *poi_list = sax_data.poi_list;
+
+    if(sax_data.sax_data.state != FINISH)
+    {
+        vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+        return FALSE;
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+/****************************************************************************
+ * ABOVE: OPEN POI **********************************************************
+ ****************************************************************************/
+
+/****************************************************************************
+ * BELOW: SAVE POI **********************************************************
+ ****************************************************************************/
+
+#define WRITE_STRING(string) { \
+    GnomeVFSResult vfs_result; \
+    GnomeVFSFileSize size; \
+    if(GNOME_VFS_OK != (vfs_result = gnome_vfs_write( \
+                    handle, (string), strlen((string)), &size))) \
+    { \
+        gchar buffer[BUFFER_SIZE]; \
+        snprintf(buffer, sizeof(buffer), \
+                "%s:\n%s\n%s", _("Error while writing to file"), \
+                _("File is incomplete."), \
+                gnome_vfs_result_to_string(vfs_result)); \
+        popup_error(_window, buffer); \
+        return FALSE; \
+    } \
+}
+
+gint
+gpx_poi_write(GtkTreeModel *model, GnomeVFSHandle *handle)
+{
+    gint num_written = 0;
+    GtkTreeIter iter;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    /* Write the header. */
+    WRITE_STRING(
+            "<?xml version=\"1.0\"?>\n"
+            "<gpx version=\"1.0\" creator=\"maemo-mapper\" "
+            "xmlns=\"http://www.topografix.com/GPX/1/0\">\n");
+
+    /* Iterate through the data model and import as desired. */
+    if(gtk_tree_model_get_iter_first(model, &iter)) do
+    {   
+        PoiInfo poi;
+        gboolean selected;
+        memset(&poi, 0, sizeof(poi));
+
+        gtk_tree_model_get(model, &iter,
+                POI_SELECTED, &selected,
+                POI_POIID, &(poi.poi_id),
+                POI_CATID, &(poi.cat_id),
+                POI_LAT, &(poi.lat),
+                POI_LON, &(poi.lon),
+                POI_LABEL, &(poi.label),
+                POI_DESC, &(poi.desc),
+                POI_CLABEL, &(poi.clabel),
+                -1);
+
+        if(selected)
+        {
+            gchar buffer[80];
+
+            WRITE_STRING("  <wpt lat=\"");
+            g_ascii_formatd(buffer, sizeof(buffer), "%.06f", poi.lat);
+            WRITE_STRING(buffer);
+            WRITE_STRING("\" lon=\"");
+            g_ascii_formatd(buffer, sizeof(buffer), "%.06f", poi.lon);
+            WRITE_STRING(buffer);
+            WRITE_STRING("\"/>\n");
+
+            if(poi.label && *poi.label)
+            {
+                WRITE_STRING("    <name>");
+                WRITE_STRING(poi.label);
+                WRITE_STRING("</name>\n");
+            }
+
+            if(poi.desc && *poi.desc)
+            {
+                WRITE_STRING("    <desc>");
+                WRITE_STRING(poi.desc);
+                WRITE_STRING("</desc>\n");
+            }
+            WRITE_STRING("  </wpt>\n");
+            ++ num_written;
+        }
+    } while(gtk_tree_model_iter_next(model, &iter));
+
+    /* Write the footer. */
+    WRITE_STRING(
+            "</gpx>\n");
+
+    vprintf("%s(): return %d\n", __PRETTY_FUNCTION__, num_written);
+    return num_written;
+}
+
+/****************************************************************************
+ * ABOVE: SAVE POI **********************************************************
+ ****************************************************************************/
+
+void
+gpx_init()
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    /* set XML_TZONE */
+    {   
+        time_t time1;
+        struct tm time2;
+        time1 = time(NULL);
+        localtime_r(&time1, &time2);
+        snprintf(XML_TZONE, sizeof(XML_TZONE), "%+03ld:%02ld",
+                (time2.tm_gmtoff / 60 / 60), (time2.tm_gmtoff / 60) % 60);
+    }
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
diff --git a/src/gpx.h b/src/gpx.h
new file mode 100644 (file)
index 0000000..9bd4575
--- /dev/null
+++ b/src/gpx.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAEMO_MAPPER_GPX_H
+#define MAEMO_MAPPER_GPX_H
+
+gboolean gpx_path_parse(Path *to_replace, gchar *buffer, gint size,
+        gint policy_old);
+gboolean gpx_path_write(Path *path, GnomeVFSHandle *handle);
+
+gint gpx_poi_parse(gchar *buffer, gint size, GList **list);
+gint gpx_poi_write(GtkTreeModel *model, GnomeVFSHandle *handle);
+
+#endif /* #ifndef MAEMO_MAPPER_GPX_H */
diff --git a/src/input.c b/src/input.c
new file mode 100644 (file)
index 0000000..4c3b27a
--- /dev/null
@@ -0,0 +1,675 @@
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define _GNU_SOURCE
+
+#include <math.h>
+#include <gdk/gdkkeysyms.h>
+#include <hildon-widgets/hildon-defines.h>
+#include <hildon-widgets/hildon-banner.h>
+
+#include "types.h"
+#include "data.h"
+#include "defines.h"
+
+#include "display.h"
+#include "gdk-pixbuf-rotate.h"
+#include "gps.h"
+#include "input.h"
+#include "maps.h"
+#include "path.h"
+#include "poi.h"
+#include "util.h"
+
+static gint _key_zoom_is_down = FALSE;
+static gint _key_zoom_new = -1;
+static gint _key_zoom_timeout_sid = 0;
+static gint _key_pan_is_down = FALSE;
+static gint _key_pan_incr_devx = 0;
+static gint _key_pan_incr_devy = 0;
+static gint _key_pan_timeout_sid = 0;
+
+static gboolean
+key_pan_timeout(CustomAction action)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+    if(_key_pan_is_down)
+    {
+        /* The pan key is still down.  Continue panning. */
+        _map_offset_devx += -_key_pan_incr_devx;
+        _map_offset_devy += -_key_pan_incr_devy;
+        MACRO_QUEUE_DRAW_AREA();
+        vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+        return TRUE;
+    }
+    else
+    {
+        /* Time is up for further action - execute the pan. */
+        gint pan_unitx = -pixel2unit(_map_offset_devx);
+        gint pan_unity = -pixel2unit(_map_offset_devy);
+        map_pan(pan_unitx, pan_unity);
+        _key_pan_timeout_sid = 0;
+        vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+        return FALSE;
+    }
+}
+
+static gboolean
+key_zoom_timeout(CustomAction action)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+    if(_key_zoom_is_down)
+    {
+        /* The zoom key is still down.  Continue zooming. */
+        if(action == CUSTOM_ACTION_ZOOM_IN)
+        {
+            /* We're currently zooming in (_zoom is decreasing). */
+            gint test = _key_zoom_new - _curr_repo->view_zoom_steps;
+            if(test >= 0)
+                /* We can zoom some more.  Hurray! */
+                _key_zoom_new = test;
+        }
+        else
+        {
+            /* We're currently zooming out (_zoom is increasing). */
+            gint test = _key_zoom_new + _curr_repo->view_zoom_steps;
+            if(test < MAX_ZOOM)
+                /* We can zoom some more.  Hurray! */
+                _key_zoom_new = test;
+        }
+        /* Tell them where they're about to zoom. */
+        {
+            gchar buffer[32];
+            snprintf(buffer, sizeof(buffer),
+                    "%s %d", _("Zoom to Level"), _key_zoom_new);
+            MACRO_BANNER_SHOW_INFO(_window, buffer);
+        }
+        vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+        return TRUE;
+    }
+    else
+    {
+        /* Time is up for further action - execute. */
+        if(_key_zoom_new != _zoom)
+            map_set_zoom(_key_zoom_new);
+        _key_pan_timeout_sid = 0;
+        _key_zoom_new = -1;
+        vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+        return FALSE;
+    }
+
+}
+
+static CustomKey
+get_custom_key_from_keyval(gint keyval)
+{
+    CustomKey custom_key;
+    printf("%s(%d)\n", __PRETTY_FUNCTION__, keyval);
+
+    switch(keyval)
+    {
+        case HILDON_HARDKEY_UP:
+            custom_key = CUSTOM_KEY_UP;
+            break;
+        case HILDON_HARDKEY_DOWN:
+            custom_key = CUSTOM_KEY_DOWN;
+            break;
+        case HILDON_HARDKEY_LEFT:
+            custom_key = CUSTOM_KEY_LEFT;
+            break;
+        case HILDON_HARDKEY_RIGHT:
+            custom_key = CUSTOM_KEY_RIGHT;
+            break;
+        case HILDON_HARDKEY_SELECT:
+            custom_key = CUSTOM_KEY_SELECT;
+            break;
+        case HILDON_HARDKEY_INCREASE:
+            custom_key = CUSTOM_KEY_INCREASE;
+            break;
+        case HILDON_HARDKEY_DECREASE:
+            custom_key = CUSTOM_KEY_DECREASE;
+            break;
+        case HILDON_HARDKEY_FULLSCREEN:
+            custom_key = CUSTOM_KEY_FULLSCREEN;
+            break;
+        case HILDON_HARDKEY_ESC:
+            custom_key = CUSTOM_KEY_ESC;
+            break;
+        default:
+            custom_key = -1;
+    }
+
+    vprintf("%s(): return %d\n", __PRETTY_FUNCTION__, custom_key);
+    return custom_key;
+}
+
+gboolean
+window_cb_key_press(GtkWidget* widget, GdkEventKey *event)
+{
+    CustomKey custom_key;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    custom_key = get_custom_key_from_keyval(event->keyval);
+    if(custom_key == -1)
+        return FALSE; /* Not our event. */
+
+    switch(_action[custom_key])
+    {
+        case CUSTOM_ACTION_PAN_NORTH:
+        case CUSTOM_ACTION_PAN_SOUTH:
+        case CUSTOM_ACTION_PAN_EAST:
+        case CUSTOM_ACTION_PAN_WEST:
+            if(!_key_pan_is_down)
+            {
+                _key_pan_is_down = TRUE;
+                if(_center_mode > 0)
+                    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(
+                                _menu_view_rotate_auto_item), FALSE);
+                if(_key_pan_timeout_sid)
+                {
+                    g_source_remove(_key_pan_timeout_sid);
+                    _key_pan_timeout_sid = 0;
+                }
+                /* Figure out new pan. */
+                switch(_action[custom_key])
+                {
+                    case CUSTOM_ACTION_PAN_NORTH:
+                        _key_pan_incr_devy = -PAN_PIXELS;
+                        break;
+                    case CUSTOM_ACTION_PAN_SOUTH:
+                        _key_pan_incr_devy = PAN_PIXELS;
+                        break;
+                    case CUSTOM_ACTION_PAN_EAST:
+                        _key_pan_incr_devx = PAN_PIXELS;
+                        break;
+                    case CUSTOM_ACTION_PAN_WEST:
+                        _key_pan_incr_devx = -PAN_PIXELS;
+                        break;
+                    default:
+                        g_printerr("Invalid action in key_pan_timeout(): %d\n",
+                                _action[custom_key]);
+                }
+                key_pan_timeout(_action[custom_key]);
+                _key_pan_timeout_sid = g_timeout_add(
+                        500, (GSourceFunc)key_pan_timeout,
+                        (gpointer)(_action[custom_key]));
+            }
+            break;
+
+        case CUSTOM_ACTION_RESET_VIEW_ANGLE:
+            if(_center_mode > 0)
+                gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(
+                            _menu_view_rotate_auto_item), FALSE);
+            map_center_rotate(0);
+            break;
+
+        case CUSTOM_ACTION_ROTATE_CLOCKWISE:
+        {
+            gint new_angle = _next_map_rotate_angle - ROTATE_DEGREES;
+            if(new_angle < 0)
+                new_angle += 360;
+            if(_center_mode > 0)
+                gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(
+                            _menu_view_rotate_auto_item), FALSE);
+            map_center_rotate(new_angle);
+            break;
+        }
+
+        case CUSTOM_ACTION_ROTATE_COUNTERCLOCKWISE:
+        {
+            gint new_angle = _next_map_rotate_angle + ROTATE_DEGREES;
+            if(new_angle >= 360)
+                new_angle -= 360;
+            if(_center_mode > 0)
+                gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(
+                            _menu_view_rotate_auto_item), FALSE);
+            map_center_rotate(new_angle);
+            break;
+        }
+
+        case CUSTOM_ACTION_TOGGLE_AUTOROTATE:
+            gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(
+                        _menu_view_rotate_auto_item), !_center_rotate);
+            break;
+
+        case CUSTOM_ACTION_TOGGLE_AUTOCENTER:
+            switch(_center_mode)
+            {
+                case CENTER_LATLON:
+                case CENTER_WAS_LEAD:
+                    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(
+                                _menu_view_ac_lead_item), TRUE);
+                    break;
+                case CENTER_LEAD:
+                case CENTER_WAS_LATLON:
+                    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(
+                                _menu_view_ac_latlon_item), TRUE);
+                    break;
+            }
+            break;
+
+        case CUSTOM_ACTION_ZOOM_IN:
+        case CUSTOM_ACTION_ZOOM_OUT:
+            if(!_key_zoom_is_down)
+            {
+                _key_zoom_is_down = TRUE;
+                if(_key_zoom_timeout_sid)
+                {
+                    g_source_remove(_key_zoom_timeout_sid);
+                    _key_zoom_timeout_sid = 0;
+                }
+                if(_key_zoom_new == -1)
+                    _key_zoom_new = _next_zoom;
+                _key_zoom_new = _key_zoom_new
+                    + (_action[custom_key] == CUSTOM_ACTION_ZOOM_IN
+                            ? -_curr_repo->view_zoom_steps
+                            : _curr_repo->view_zoom_steps);
+                BOUND(_key_zoom_new, 0, MAX_ZOOM);
+                {
+                    gchar buffer[80];
+                    snprintf(buffer, sizeof(buffer),"%s %d",
+                            _("Zoom to Level"), _key_zoom_new);
+                    MACRO_BANNER_SHOW_INFO(_window, buffer);
+                }
+                _key_zoom_timeout_sid = g_timeout_add(
+                        500, (GSourceFunc)key_zoom_timeout,
+                        (gpointer)(_action[custom_key]));
+            }
+            break;
+
+        case CUSTOM_ACTION_TOGGLE_FULLSCREEN:
+            gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(
+                        _menu_view_fullscreen_item), !_fullscreen);
+            break;
+
+        case CUSTOM_ACTION_TOGGLE_TRACKS:
+            switch(_show_paths)
+            {
+                case 0:
+                    /* Nothing shown, nothing saved; just set both. */
+                    _show_paths = TRACKS_MASK | ROUTES_MASK;
+                    break;
+                case TRACKS_MASK << 16:
+                case ROUTES_MASK << 16:
+                case (ROUTES_MASK | TRACKS_MASK) << 16:
+                    /* Something was saved and nothing changed since.
+                     * Restore saved. */
+                    _show_paths = _show_paths >> 16;
+                    break;
+                default:
+                    /* There is no history, or they changed something
+                     * since the last historical change. Save and
+                     * clear. */
+                    _show_paths = _show_paths << 16;
+            }
+            gtk_check_menu_item_set_active(
+                    GTK_CHECK_MENU_ITEM(_menu_view_show_routes_item),
+                    _show_paths & ROUTES_MASK);
+
+            gtk_check_menu_item_set_active(
+                    GTK_CHECK_MENU_ITEM(_menu_view_show_tracks_item),
+                    _show_paths & TRACKS_MASK);
+
+        case CUSTOM_ACTION_TOGGLE_SCALE:
+            gtk_check_menu_item_set_active(
+                    GTK_CHECK_MENU_ITEM(_menu_view_show_scale_item),
+                    !_show_scale);
+            break;
+
+        case CUSTOM_ACTION_TOGGLE_POI:
+            gtk_check_menu_item_set_active(
+                    GTK_CHECK_MENU_ITEM(_menu_view_show_poi_item),
+                    !_show_poi);
+            break;
+        case CUSTOM_ACTION_CHANGE_REPO: {
+            GList *curr = g_list_find(_repo_list, _curr_repo);
+            if(!curr)
+                break;
+
+            /* Loop until we reach a next-able repo, or until we get
+             * back to the current repo. */
+            while((curr = (curr->next ? curr->next : _repo_list))
+                    && !((RepoData*)curr->data)->nextable
+                    && curr->data != _curr_repo) { }
+
+            if(curr->data != _curr_repo)
+            {
+                repo_set_curr(curr->data);
+                gtk_check_menu_item_set_active(
+                        GTK_CHECK_MENU_ITEM(_curr_repo->menu_item),
+                        TRUE);
+            }
+            else
+            {
+                popup_error(_window,
+                    _("There are no other next-able repositories."));
+            }
+            break;
+        }
+
+        case CUSTOM_ACTION_RESET_BLUETOOTH:
+            reset_bluetooth();
+            break;
+
+        case CUSTOM_ACTION_ROUTE_DISTNEXT:
+            route_show_distance_to_next();
+            break;
+
+        case CUSTOM_ACTION_ROUTE_DISTLAST:
+            route_show_distance_to_last();
+            break;
+
+        case CUSTOM_ACTION_TRACK_BREAK:
+            track_insert_break(TRUE);
+            break;
+
+        case CUSTOM_ACTION_TRACK_CLEAR:
+            track_clear();
+            break;
+
+        case CUSTOM_ACTION_TRACK_DISTLAST:
+            track_show_distance_from_last();
+            break;
+
+        case CUSTOM_ACTION_TRACK_DISTFIRST:
+            track_show_distance_from_first();
+            break;
+
+        case CUSTOM_ACTION_TOGGLE_GPS:
+            gtk_check_menu_item_set_active(
+                    GTK_CHECK_MENU_ITEM(_menu_enable_gps_item),
+                    !_enable_gps);
+            break;
+
+        case CUSTOM_ACTION_TOGGLE_GPSINFO:
+            gtk_check_menu_item_set_active(
+                    GTK_CHECK_MENU_ITEM(_menu_gps_show_info_item),
+                    !_gps_info);
+            break;
+
+        case CUSTOM_ACTION_TOGGLE_SPEEDLIMIT:
+            _speed_limit_on ^= 1;
+            break;
+
+        default:
+            vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+            return FALSE;
+    }
+
+    return TRUE;
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+}
+
+gboolean
+window_cb_key_release(GtkWidget* widget, GdkEventKey *event)
+{
+    CustomKey custom_key;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    custom_key = get_custom_key_from_keyval(event->keyval);
+    if(custom_key < 0)
+        return FALSE; /* Not our event. */
+
+    switch(_action[custom_key])
+    {
+        case CUSTOM_ACTION_ZOOM_IN:
+        case CUSTOM_ACTION_ZOOM_OUT:
+            if(_key_zoom_timeout_sid)
+            {
+                g_source_remove(_key_zoom_timeout_sid);
+                _key_zoom_timeout_sid = 0;
+                _key_zoom_timeout_sid = g_timeout_add(
+                        500, (GSourceFunc)key_zoom_timeout, NULL);
+            }
+            _key_zoom_is_down = FALSE;
+            return TRUE;
+
+        case CUSTOM_ACTION_PAN_NORTH:
+        case CUSTOM_ACTION_PAN_SOUTH:
+        case CUSTOM_ACTION_PAN_EAST:
+        case CUSTOM_ACTION_PAN_WEST:
+            if(_key_pan_timeout_sid)
+            {
+                g_source_remove(_key_pan_timeout_sid);
+                _key_pan_timeout_sid = g_timeout_add(
+                        500, (GSourceFunc)key_pan_timeout, NULL);
+            }
+            _key_pan_is_down = FALSE;
+            _key_pan_incr_devx = 0;
+            _key_pan_incr_devy = 0;
+            return TRUE;
+
+        default:
+            return FALSE;
+    }
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+gboolean
+map_cb_motion_notify(GtkWidget *widget, GdkEventMotion *event)
+{
+    gint x, y;
+    GdkModifierType state;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(!_mouse_is_down)
+        return FALSE;
+
+    if(event->is_hint)
+        gdk_window_get_pointer(event->window, &x, &y, &state);
+    else
+    {
+        x = event->x;
+        y = event->y;
+        state = event->state;
+    }
+
+    if(_mouse_is_dragging)
+    {
+        /* Already in the process of dragging.  Set the offset. */
+        _map_offset_devx = x - _cmenu_position_x;
+        _map_offset_devy = y - _cmenu_position_y;
+        MACRO_QUEUE_DRAW_AREA();
+    }
+    else
+    {
+        gint diffx = x - _cmenu_position_x - _map_offset_devx;
+        gint diffy = y - _cmenu_position_y - _map_offset_devy;
+        if(diffx * diffx + diffy + diffy > 100)
+        {
+            _mouse_is_dragging = TRUE;
+        }
+    }
+
+    /* Return FALSE to allow context menu to work. */
+    vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+gboolean
+map_cb_button_press(GtkWidget *widget, GdkEventButton *event)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(!_mouse_is_down)
+    {
+        _cmenu_position_x = event->x + 0.5 - _map_offset_devx;
+        _cmenu_position_y = event->y + 0.5 - _map_offset_devy;
+        g_mutex_lock(_mouse_mutex);
+        _mouse_is_down = TRUE;
+    }
+
+    /* Return FALSE to allow context menu to work. */
+    vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+    return FALSE;
+}
+
+gboolean
+map_cb_button_release(GtkWidget *widget, GdkEventButton *event)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(!_mouse_is_down)
+    {
+        /* We didn't know about it anyway.  Return FALSE. */
+        vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+        return FALSE;
+    }
+
+    _mouse_is_down = FALSE;
+
+#ifdef DEBUG
+    if(event->button != 1)
+    {   
+        screen2unit((gint)(event->x + 0.5), (gint)(event->y + 0.5),
+                _pos.unitx, _pos.unity);
+        unit2latlon(_pos.unitx, _pos.unity, _gps.lat, _gps.lon);
+        if(track_add(time(NULL), FALSE))
+        {
+            /* Move mark to new location. */
+            map_refresh_mark(FALSE);
+        }
+        else
+        {
+            map_move_mark();
+        }
+    }
+    else
+#endif
+    if(_mouse_is_dragging)
+    {
+        Point clkpt;
+
+        _mouse_is_dragging = FALSE;
+
+        screen2unit(_screen_halfwidth_pixels, _screen_halfheight_pixels,
+                clkpt.unitx, clkpt.unity);
+
+        if(_center_mode > 0)
+        {
+            gfloat matrix[4];
+            gint mvpt_unitx, mvpt_unity;
+            gfloat new_offset_unitx, new_offset_unity;
+            /* If auto-center is enabled (meaning that panning will cause the
+             * view the rotate according to the heading), rotate the new
+             * unitx/unity around the mvpt, by any changes in _gps.heading
+             * since the last time _map_rotate_angle was updated.  The end
+             * result is that the point the user is moving stays in the same
+             * relative point, even if the heading has since changed. */
+            gdk_pixbuf_rotate_matrix_fill_for_rotation(matrix,
+                    deg2rad(_gps.heading - _next_map_rotate_angle));
+            buf2unit(_cmenu_position_x, _cmenu_position_y,
+                    mvpt_unitx, mvpt_unity);
+            gdk_pixbuf_rotate_vector(&new_offset_unitx, &new_offset_unity,
+                    matrix,
+                    (gint)(clkpt.unitx - mvpt_unitx),
+                    (gint)(clkpt.unity -mvpt_unity));
+            clkpt.unitx = mvpt_unitx + new_offset_unitx;
+            clkpt.unity = mvpt_unity + new_offset_unity;
+        }
+
+        if(_center_mode > 0)
+            gtk_check_menu_item_set_active(
+                    GTK_CHECK_MENU_ITEM(_menu_view_ac_none_item), TRUE);
+
+        map_center_unit(clkpt);
+    }
+    else
+    {
+        gboolean selected_point = FALSE;
+        Point clkpt;
+        screen2unit(event->x, event->y, clkpt.unitx, clkpt.unity);
+
+        if(_show_poi && (_poi_zoom > _zoom))
+        {
+            PoiInfo poi;
+            selected_point = select_poi(
+                    clkpt.unitx, clkpt.unity, &poi, TRUE);
+            if(selected_point)
+            {
+                gchar *banner;
+                banner = g_strdup_printf("%s (%s)", poi.label, poi.clabel);
+                MACRO_BANNER_SHOW_INFO(_window, banner);
+                g_free(banner);
+                g_free(poi.label);
+                g_free(poi.desc);
+                g_free(poi.clabel);
+            }
+        }
+        else if(_show_paths & ROUTES_MASK && _route.whead <= _route.wtail)
+        {
+            WayPoint *way = find_nearest_waypoint(
+                    clkpt.unitx, clkpt.unity);
+            if(way)
+            {
+                selected_point = TRUE;
+                MACRO_BANNER_SHOW_INFO(_window, way->desc);
+            }
+        }
+        if(!selected_point)
+        {
+            if(_center_mode > 0)
+                gtk_check_menu_item_set_active(
+                        GTK_CHECK_MENU_ITEM(_menu_view_ac_none_item), TRUE);
+            map_center_unit_full(clkpt, _next_zoom,
+                    _center_mode > 0 && _center_rotate
+                    ? _gps.heading : _next_map_rotate_angle);
+        }
+    }
+
+    g_mutex_unlock(_mouse_mutex);
+
+    /* Return FALSE to avoid context menu (if it hasn't popped up already). */
+    vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+    return FALSE;
+}
+
+void
+input_init()
+{
+    printf("%s():\n", __PRETTY_FUNCTION__);
+
+    g_signal_connect(G_OBJECT(_window), "key_press_event",
+            G_CALLBACK(window_cb_key_press), NULL);
+
+    g_signal_connect(G_OBJECT(_window), "key_release_event",
+            G_CALLBACK(window_cb_key_release), NULL);
+
+    g_signal_connect(G_OBJECT(_map_widget), "motion_notify_event",
+            G_CALLBACK(map_cb_motion_notify), NULL);
+
+    g_signal_connect(G_OBJECT(_map_widget), "button_press_event",
+            G_CALLBACK(map_cb_button_press), NULL);
+
+    g_signal_connect(G_OBJECT(_map_widget), "button_release_event",
+            G_CALLBACK(map_cb_button_release), NULL);
+
+    gtk_widget_add_events(_map_widget,
+            GDK_EXPOSURE_MASK
+            | GDK_POINTER_MOTION_MASK
+            | GDK_POINTER_MOTION_HINT_MASK
+            | GDK_BUTTON_PRESS_MASK
+            | GDK_BUTTON_RELEASE_MASK);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
diff --git a/src/input.h b/src/input.h
new file mode 100644 (file)
index 0000000..4c22aec
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAEMO_MAPPER_INPUT_H
+#define MAEMO_MAPPER_INPUT_H
+
+void input_init();
+
+#endif /* ifndef MAEMO_MAPPER_INPUT_H */
diff --git a/src/maemo-mapper.c b/src/maemo-mapper.c
deleted file mode 100644 (file)
index 0347a0d..0000000
+++ /dev/null
@@ -1,14370 +0,0 @@
-/*
- * This file is part of maemo-mapper
- *
- * Copyright (C) 2006-2007 John Costigan.
- *
- * POI and GPS-Info code originally written by Cezary Jackiewicz.
- *
- * Default map data provided by http://www.openstreetmap.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-
-#define _GNU_SOURCE
-
-#define _(String) gettext(String)
-
-#include <config.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <stddef.h>
-#include <locale.h>
-#include <math.h>
-#include <errno.h>
-#include <sys/wait.h>
-#include <glib/gstdio.h>
-#include <gtk/gtk.h>
-#include <fcntl.h>
-#include <gdk/gdkkeysyms.h>
-#include <libosso.h>
-#include <osso-helplib.h>
-#include <osso-ic-dbus.h>
-#include <osso-ic.h>
-#include <dbus/dbus-glib.h>
-#include <bt-dbus.h>
-#include <hildon-widgets/hildon-program.h>
-#include <hildon-widgets/hildon-controlbar.h>
-#include <hildon-widgets/hildon-note.h>
-#include <hildon-widgets/hildon-color-button.h>
-#include <hildon-widgets/hildon-file-chooser-dialog.h>
-#include <hildon-widgets/hildon-number-editor.h>
-#include <hildon-widgets/hildon-banner.h>
-#include <hildon-widgets/hildon-system-sound.h>
-#include <hildon-widgets/hildon-input-mode-hint.h>
-#include <libgnomevfs/gnome-vfs.h>
-#include <curl/multi.h>
-#include <gconf/gconf-client.h>
-#include <libxml/parser.h>
-#include <device_symbols.h>
-
-#include <libintl.h>
-#include <locale.h>
-
-#include <sqlite3.h>
-
-/****************************************************************************
- * BELOW: DEFINES ***********************************************************
- ****************************************************************************/
-
-#ifndef DEBUG
-#define printf(...)
-#endif
-
-/* Set the below if to determine whether to get verbose output. */
-#if 0
-#define vprintf printf
-#else
-#define vprintf(...)
-#endif
-
-#define BOUND(x, a, b) { \
-    if((x) < (a)) \
-        (x) = (a); \
-    else if((x) > (b)) \
-        (x) = (b); \
-}
-
-#define PI   (3.14159265358979323846f)
-
-/** MAX_ZOOM defines the largest map zoom level we will download.
- * (MAX_ZOOM - 1) is the largest map zoom level that the user can zoom to.
- */
-#define MAX_ZOOM 16
-
-#define TILE_SIZE_PIXELS (256)
-#define TILE_SIZE_P2 (8)
-#define BUF_WIDTH_TILES (4)
-#define BUF_HEIGHT_TILES (3)
-#define BUF_WIDTH_PIXELS (1024)
-#define BUF_HEIGHT_PIXELS (768)
-
-#define ARRAY_CHUNK_SIZE (1024)
-
-#define BUFFER_SIZE (2048)
-
-#define WORLD_SIZE_UNITS (2 << (MAX_ZOOM + TILE_SIZE_P2))
-
-#define tile2grid(tile) ((tile) << 3)
-#define grid2tile(grid) ((grid) >> 3)
-#define tile2pixel(tile) ((tile) << 8)
-#define pixel2tile(pixel) ((pixel) >> 8)
-#define tile2unit(tile) ((tile) << (8 + _zoom))
-#define unit2tile(unit) ((unit) >> (8 + _zoom))
-#define tile2zunit(tile, zoom) ((tile) << (8 + zoom))
-#define unit2ztile(unit, zoom) ((unit) >> (8 + zoom))
-
-#define grid2pixel(grid) ((grid) << 5)
-#define pixel2grid(pixel) ((pixel) >> 5)
-#define grid2unit(grid) ((grid) << (5 + _zoom))
-#define unit2grid(unit) ((unit) >> (5 + _zoom))
-
-#define pixel2unit(pixel) ((pixel) << _zoom)
-#define unit2pixel(pixel) ((pixel) >> _zoom)
-#define pixel2zunit(pixel, zoom) ((pixel) << (zoom))
-
-#define unit2bufx(unit) (unit2pixel(unit) - tile2pixel(_base_tilex))
-#define bufx2unit(x) (pixel2unit(x) + tile2unit(_base_tilex))
-#define unit2bufy(unit) (unit2pixel(unit) - tile2pixel(_base_tiley))
-#define bufy2unit(y) (pixel2unit(y) + tile2unit(_base_tiley))
-
-#define unit2x(unit) (unit2pixel(unit) - tile2pixel(_base_tilex) - _offsetx)
-#define x2unit(x) (pixel2unit(x + _offsetx) + tile2unit(_base_tilex))
-#define unit2y(unit) (unit2pixel(unit) - tile2pixel(_base_tiley) - _offsety)
-#define y2unit(y) (pixel2unit(y + _offsety) + tile2unit(_base_tiley))
-
-#define leadx2unit() (_pos.unitx + (_lead_ratio) * pixel2unit(_vel_offsetx))
-#define leady2unit() (_pos.unity + (0.6f*_lead_ratio)*pixel2unit(_vel_offsety))
-
-/* Pans are done two "grids" at a time, or 64 pixels. */
-#define PAN_UNITS (grid2unit(2))
-
-#define INITIAL_DOWNLOAD_RETRIES (3)
-
-#define GCONF_KEY_PREFIX "/apps/maemo/maemo-mapper"
-#define GCONF_KEY_RCVR_MAC GCONF_KEY_PREFIX"/receiver_mac"
-#define GCONF_KEY_RCVR_CHAN GCONF_KEY_PREFIX"/receiver_channel"
-#define GCONF_KEY_MAP_URI_FORMAT GCONF_KEY_PREFIX"/map_uri_format"
-#define GCONF_KEY_MAP_ZOOM_STEPS GCONF_KEY_PREFIX"/map_zoom_steps"
-#define GCONF_KEY_MAP_DIR_NAME GCONF_KEY_PREFIX"/map_cache_dir"
-#define GCONF_KEY_AUTO_DOWNLOAD GCONF_KEY_PREFIX"/auto_download"
-#define GCONF_KEY_CENTER_SENSITIVITY GCONF_KEY_PREFIX"/center_sensitivity"
-#define GCONF_KEY_ANNOUNCE_NOTICE GCONF_KEY_PREFIX"/announce_notice"
-#define GCONF_KEY_DRAW_WIDTH GCONF_KEY_PREFIX"/draw_width"
-#define GCONF_KEY_ENABLE_VOICE GCONF_KEY_PREFIX"/enable_voice"
-#define GCONF_KEY_VOICE_SPEED GCONF_KEY_PREFIX"/voice_speed"
-#define GCONF_KEY_VOICE_PITCH GCONF_KEY_PREFIX"/voice_pitch"
-#define GCONF_KEY_FULLSCREEN GCONF_KEY_PREFIX"/fullscreen"
-#define GCONF_KEY_ALWAYS_KEEP_ON GCONF_KEY_PREFIX"/always_keep_on"
-#define GCONF_KEY_UNITS GCONF_KEY_PREFIX"/units"
-#define GCONF_KEY_SPEED_LIMIT_ON GCONF_KEY_PREFIX"/speed_limit_on"
-#define GCONF_KEY_SPEED_LIMIT GCONF_KEY_PREFIX"/speed_limit"
-#define GCONF_KEY_SPEED_LOCATION GCONF_KEY_PREFIX"/speed_location"
-#define GCONF_KEY_INFO_FONT_SIZE GCONF_KEY_PREFIX"/info_font_size"
-
-#define GCONF_KEY_POI_DB GCONF_KEY_PREFIX"/poi_db"
-#define GCONF_KEY_POI_ZOOM GCONF_KEY_PREFIX"/poi_zoom"
-
-#define GCONF_KEY_AUTOCENTER_MODE GCONF_KEY_PREFIX"/autocenter_mode"
-#define GCONF_KEY_LEAD_AMOUNT GCONF_KEY_PREFIX"/lead_amount"
-#define GCONF_KEY_LAT GCONF_KEY_PREFIX"/last_latitude"
-#define GCONF_KEY_LON GCONF_KEY_PREFIX"/last_longitude"
-#define GCONF_KEY_CENTER_LAT GCONF_KEY_PREFIX"/center_latitude"
-#define GCONF_KEY_CENTER_LON GCONF_KEY_PREFIX"/center_longitude"
-#define GCONF_KEY_ZOOM GCONF_KEY_PREFIX"/zoom"
-#define GCONF_KEY_ROUTEDIR GCONF_KEY_PREFIX"/route_directory"
-#define GCONF_KEY_TRACKFILE GCONF_KEY_PREFIX"/track_file"
-#define GCONF_KEY_SHOWZOOMLEVEL GCONF_KEY_PREFIX"/show_zoomlevel"
-#define GCONF_KEY_SHOWSCALE GCONF_KEY_PREFIX"/show_scale"
-#define GCONF_KEY_SHOWTRACKS GCONF_KEY_PREFIX"/show_tracks"
-#define GCONF_KEY_SHOWROUTES GCONF_KEY_PREFIX"/show_routes"
-#define GCONF_KEY_SHOWVELVEC GCONF_KEY_PREFIX"/show_velocity_vector"
-#define GCONF_KEY_SHOWPOIS GCONF_KEY_PREFIX"/show_poi"
-#define GCONF_KEY_ENABLE_GPS GCONF_KEY_PREFIX"/enable_gps"
-#define GCONF_KEY_ROUTE_LOCATIONS GCONF_KEY_PREFIX"/route_locations"
-#define GCONF_KEY_REPOSITORIES GCONF_KEY_PREFIX"/repositories"
-#define GCONF_KEY_CURRREPO GCONF_KEY_PREFIX"/curr_repo"
-#define GCONF_KEY_GPS_INFO GCONF_KEY_PREFIX"/gps_info"
-#define GCONF_KEY_ROUTE_DL_URL GCONF_KEY_PREFIX"/route_dl_url"
-#define GCONF_KEY_ROUTE_DL_RADIUS GCONF_KEY_PREFIX"/route_dl_radius"
-#define GCONF_KEY_DEG_FORMAT GCONF_KEY_PREFIX"/deg_format"
-
-#define GCONF_KEY_DISCONNECT_ON_COVER \
-  "/system/osso/connectivity/IAP/disconnect_on_cover"
-
-#define GCONF_KEY_HTTP_PROXY_PREFIX "/system/http_proxy"
-#define GCONF_KEY_HTTP_PROXY_ON GCONF_KEY_HTTP_PROXY_PREFIX"/use_http_proxy"
-#define GCONF_KEY_HTTP_PROXY_HOST GCONF_KEY_HTTP_PROXY_PREFIX"/host"
-#define GCONF_KEY_HTTP_PROXY_PORT GCONF_KEY_HTTP_PROXY_PREFIX"/port"
-
-#define CONFIG_DIR_NAME "~/.maemo-mapper/"
-#define CONFIG_FILE_ROUTE "route.gpx"
-#define CONFIG_FILE_TRACK "track.gpx"
-
-#define REPO_DEFAULT_NAME "OpenStreet"
-#define REPO_DEFAULT_CACHE_BASE "~/MyDocs/.documents/Maps/"
-#define REPO_DEFAULT_CACHE_DIR REPO_DEFAULT_CACHE_BASE"OpenStreet"
-#define REPO_DEFAULT_MAP_URI "http://tile.openstreetmap.org/%0d/%d/%d.png"
-#define REPO_DEFAULT_DL_ZOOM_STEPS (2)
-#define REPO_DEFAULT_VIEW_ZOOM_STEPS (1)
-
-#define XML_DATE_FORMAT "%FT%T"
-
-#define HELP_ID_PREFIX "help_maemomapper_"
-#define HELP_ID_INTRO HELP_ID_PREFIX"intro"
-#define HELP_ID_GETSTARTED HELP_ID_PREFIX"getstarted"
-#define HELP_ID_ABOUT HELP_ID_PREFIX"about"
-#define HELP_ID_SETTINGS HELP_ID_PREFIX"settings"
-#define HELP_ID_REPOMAN HELP_ID_PREFIX"repoman"
-#define HELP_ID_MAPMAN HELP_ID_PREFIX"mapman"
-#define HELP_ID_DOWNROUTE HELP_ID_PREFIX"downroute"
-#define HELP_ID_POICAT HELP_ID_PREFIX"poicat"
-
-#define MACRO_RECALC_CENTER(center_unitx, center_unity) { \
-    switch(_center_mode) \
-    { \
-        case CENTER_LEAD: \
-            center_unitx = leadx2unit(); \
-            center_unity = leady2unit(); \
-            break; \
-        case CENTER_LATLON: \
-            center_unitx = _pos.unitx; \
-            center_unity = _pos.unity; \
-            break; \
-        default: \
-            center_unitx = _center.unitx; \
-            center_unity = _center.unity; \
-            ; \
-    } \
-};
-
-#define MERCATOR_SPAN (-6.28318377773622f)
-#define MERCATOR_TOP (3.14159188886811f)
-#define latlon2unit(lat, lon, unitx, unity) { \
-    gfloat tmp; \
-    unitx = (lon + 180.f) * (WORLD_SIZE_UNITS / 360.f) + 0.5f; \
-    tmp = sinf(lat * (PI / 180.f)); \
-    unity = 0.5f + (WORLD_SIZE_UNITS / MERCATOR_SPAN) \
-        * (logf((1.f + tmp) / (1.f - tmp)) * 0.5f - MERCATOR_TOP); \
-}
-
-#define unit2latlon(unitx, unity, lat, lon) { \
-    (lon) = ((unitx) * (360.f / WORLD_SIZE_UNITS)) - 180.f; \
-    (lat) = (360.f * (atanf(expf(((unity) \
-                                  * (MERCATOR_SPAN / WORLD_SIZE_UNITS)) \
-                     + MERCATOR_TOP)))) * (1.f / PI) - 90.f; \
-}
-
-#define MACRO_RECALC_OFFSET() { \
-    _offsetx = grid2pixel( \
-            unit2grid(_center.unitx) \
-            - _screen_grids_halfwidth \
-            - tile2grid(_base_tilex)); \
-    _offsety = grid2pixel( \
-            unit2grid(_center.unity) \
-            - _screen_grids_halfheight \
-            - tile2grid(_base_tiley)); \
-}
-
-#define MACRO_RECALC_FOCUS_BASE() { \
-    _focus.unitx = x2unit(_screen_width_pixels * _center_ratio / 20); \
-    _focus.unity = y2unit(_screen_height_pixels * _center_ratio / 20); \
-}
-
-#define MACRO_RECALC_FOCUS_SIZE() { \
-    _focus_unitwidth = pixel2unit( \
-            (10 - _center_ratio) * _screen_width_pixels / 10); \
-    _focus_unitheight = pixel2unit( \
-            (10 - _center_ratio) * _screen_height_pixels / 10); \
-}
-
-#define MACRO_RECALC_CENTER_BOUNDS() { \
-  _min_center.unitx = pixel2unit(grid2pixel(_screen_grids_halfwidth)); \
-  _min_center.unity = pixel2unit(grid2pixel(_screen_grids_halfheight)); \
-  _max_center.unitx = WORLD_SIZE_UNITS-grid2unit(_screen_grids_halfwidth) - 1;\
-  _max_center.unity = WORLD_SIZE_UNITS-grid2unit(_screen_grids_halfheight)- 1;\
-}
-
-#define MACRO_PATH_INIT(path) { \
-    (path).head = (path).tail = g_new(Point, ARRAY_CHUNK_SIZE); \
-    *((path).tail) = _point_null; \
-    (path).cap = (path).head + ARRAY_CHUNK_SIZE; \
-    (path).whead = g_new(WayPoint, ARRAY_CHUNK_SIZE); \
-    (path).wtail = (path).whead - 1; \
-    (path).wcap = (path).whead + ARRAY_CHUNK_SIZE; \
-}
-
-#define MACRO_PATH_FREE(path) if((path).head) { \
-    WayPoint *curr; \
-    g_free((path).head); \
-    (path).head = (path).tail = (path).cap = NULL; \
-    for(curr = (path).whead - 1; curr++ != (path).wtail; ) \
-        g_free(curr->desc); \
-    g_free((path).whead); \
-    (path).whead = (path).wtail = (path).wcap = NULL; \
-}
-
-#define MACRO_PATH_INCREMENT_TAIL(route) { \
-    if(++(route).tail == (route).cap) \
-        path_resize(&(route), (route).cap - (route).head + ARRAY_CHUNK_SIZE);\
-}
-
-#define MACRO_PATH_INCREMENT_WTAIL(route) { \
-    if(++(route).wtail == (route).wcap) \
-        path_wresize(&(route), \
-                (route).wcap - (route).whead + ARRAY_CHUNK_SIZE); \
-}
-
-#define DISTANCE_SQUARED(a, b) \
-   ((guint64)((((gint64)(b).unitx)-(a).unitx)*(((gint64)(b).unitx)-(a).unitx))\
-  + (guint64)((((gint64)(b).unity)-(a).unity)*(((gint64)(b).unity)-(a).unity)))
-
-#define MACRO_QUEUE_DRAW_AREA() \
-    gtk_widget_queue_draw_area( \
-            _map_widget, \
-            0, 0, \
-            _screen_width_pixels, \
-            _screen_height_pixels)
-
-/* Render all on-map metadata an annotations, including POI and paths. */
-#define MACRO_MAP_RENDER_DATA() { \
-    if(_show_poi) \
-        map_render_poi(); \
-    if(_show_tracks > 0) \
-        map_render_paths(); \
-}
-
-#define KEEP_DISPLAY_ON() { \
-    /* Note that the flag means keep on ONLY when fullscreen. */ \
-    if(_always_keep_on || _fullscreen) \
-    { \
-        osso_display_state_on(_osso); \
-        osso_display_blanking_pause(_osso); \
-    } \
-}
-
-#define LL_FMT_LEN 20
-#define lat_format(A, B) deg_format((A), (B), 'S', 'N')
-#define lon_format(A, B) deg_format((A), (B), 'W', 'E')
-
-#define TRACKS_MASK 0x00000001
-#define ROUTES_MASK 0x00000002
-
-#define g_timeout_add(I, F, D) g_timeout_add_full(G_PRIORITY_DEFAULT_IDLE, \
-          (I), (F), (D), NULL)
-
-#define MACRO_CURL_EASY_INIT(C) { \
-    C = curl_easy_init(); \
-    curl_easy_setopt(C, CURLOPT_NOPROGRESS, 1); \
-    curl_easy_setopt(C, CURLOPT_FOLLOWLOCATION, 1); \
-    curl_easy_setopt(C, CURLOPT_FAILONERROR, 1); \
-    curl_easy_setopt(C, CURLOPT_USERAGENT, \
-            "Mozilla/5.0 (X11; U; Linux i686; en-US; " \
-            "rv:1.8.0.4) Gecko/20060701 Firefox/1.5.0.4"); \
-    curl_easy_setopt(C, CURLOPT_TIMEOUT, 30); \
-    curl_easy_setopt(C, CURLOPT_CONNECTTIMEOUT, 10); \
-    if(_iap_http_proxy_host) \
-    { \
-        curl_easy_setopt(C, CURLOPT_PROXY, _iap_http_proxy_host); \
-        if(_iap_http_proxy_port) \
-            curl_easy_setopt(C, CURLOPT_PROXYPORT, _iap_http_proxy_port); \
-    } \
-}
-
-#define MACRO_BANNER_SHOW_INFO(A, S) { \
-    gchar *my_macro_buffer = g_strdup_printf("<span size='%s'>%s</span>", \
-            INFO_FONT_TEXT[_info_font_size], (S)); \
-    hildon_banner_show_information_with_markup(A, NULL, my_macro_buffer); \
-    g_free(my_macro_buffer); \
-}
-
-/****************************************************************************
- * ABOVE: DEFINES ***********************************************************
- ****************************************************************************/
-
-/****************************************************************************
- * BELOW: MARSHALLERS *******************************************************
- ****************************************************************************/
-
-
-#ifndef __g_cclosure_user_marshal_MARSHAL_H__
-#define __g_cclosure_user_marshal_MARSHAL_H__
-
-#include    <glib-object.h>
-
-G_BEGIN_DECLS
-
-#ifdef G_ENABLE_DEBUG
-#define g_marshal_value_peek_boolean(v)  g_value_get_boolean (v)
-#define g_marshal_value_peek_char(v)     g_value_get_char (v)
-#define g_marshal_value_peek_uchar(v)    g_value_get_uchar (v)
-#define g_marshal_value_peek_int(v)      g_value_get_int (v)
-#define g_marshal_value_peek_uint(v)     g_value_get_uint (v)
-#define g_marshal_value_peek_long(v)     g_value_get_long (v)
-#define g_marshal_value_peek_ulong(v)    g_value_get_ulong (v)
-#define g_marshal_value_peek_int64(v)    g_value_get_int64 (v)
-#define g_marshal_value_peek_uint64(v)   g_value_get_uint64 (v)
-#define g_marshal_value_peek_enum(v)     g_value_get_enum (v)
-#define g_marshal_value_peek_flags(v)    g_value_get_flags (v)
-#define g_marshal_value_peek_float(v)    g_value_get_float (v)
-#define g_marshal_value_peek_double(v)   g_value_get_double (v)
-#define g_marshal_value_peek_string(v)   (char*) g_value_get_string (v)
-#define g_marshal_value_peek_param(v)    g_value_get_param (v)
-#define g_marshal_value_peek_boxed(v)    g_value_get_boxed (v)
-#define g_marshal_value_peek_pointer(v)  g_value_get_pointer (v)
-#define g_marshal_value_peek_object(v)   g_value_get_object (v)
-#else /* !G_ENABLE_DEBUG */
-/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
- *          Do not access GValues directly in your code. Instead, use the
- *          g_value_get_*() functions
- */
-#define g_marshal_value_peek_boolean(v)  (v)->data[0].v_int
-#define g_marshal_value_peek_char(v)     (v)->data[0].v_int
-#define g_marshal_value_peek_uchar(v)    (v)->data[0].v_uint
-#define g_marshal_value_peek_int(v)      (v)->data[0].v_int
-#define g_marshal_value_peek_uint(v)     (v)->data[0].v_uint
-#define g_marshal_value_peek_long(v)     (v)->data[0].v_long
-#define g_marshal_value_peek_ulong(v)    (v)->data[0].v_ulong
-#define g_marshal_value_peek_int64(v)    (v)->data[0].v_int64
-#define g_marshal_value_peek_uint64(v)   (v)->data[0].v_uint64
-#define g_marshal_value_peek_enum(v)     (v)->data[0].v_long
-#define g_marshal_value_peek_flags(v)    (v)->data[0].v_ulong
-#define g_marshal_value_peek_float(v)    (v)->data[0].v_float
-#define g_marshal_value_peek_double(v)   (v)->data[0].v_double
-#define g_marshal_value_peek_string(v)   (v)->data[0].v_pointer
-#define g_marshal_value_peek_param(v)    (v)->data[0].v_pointer
-#define g_marshal_value_peek_boxed(v)    (v)->data[0].v_pointer
-#define g_marshal_value_peek_pointer(v)  (v)->data[0].v_pointer
-#define g_marshal_value_peek_object(v)   (v)->data[0].v_pointer
-#endif /* !G_ENABLE_DEBUG */
-
-
-/* VOID:STRING,STRING,POINTER,UCHAR,UINT (marshal.list:1) */
-extern void g_cclosure_user_marshal_VOID__STRING_STRING_POINTER_UCHAR_UINT (GClosure     *closure,
-                                                                            GValue       *return_value,
-                                                                            guint         n_param_values,
-                                                                            const GValue *param_values,
-                                                                            gpointer      invocation_hint,
-                                                                            gpointer      marshal_data);
-void
-g_cclosure_user_marshal_VOID__STRING_STRING_POINTER_UCHAR_UINT (GClosure     *closure,
-                                                                GValue       *return_value,
-                                                                guint         n_param_values,
-                                                                const GValue *param_values,
-                                                                gpointer      invocation_hint,
-                                                                gpointer      marshal_data)
-{
-  typedef void (*GMarshalFunc_VOID__STRING_STRING_POINTER_UCHAR_UINT) (gpointer     data1,
-                                                                       gpointer     arg_1,
-                                                                       gpointer     arg_2,
-                                                                       gpointer     arg_3,
-                                                                       guchar       arg_4,
-                                                                       guint        arg_5,
-                                                                       gpointer     data2);
-  register GMarshalFunc_VOID__STRING_STRING_POINTER_UCHAR_UINT callback;
-  register GCClosure *cc = (GCClosure*) closure;
-  register gpointer data1, data2;
-
-  g_return_if_fail (n_param_values == 6);
-
-  if (G_CCLOSURE_SWAP_DATA (closure))
-    {
-      data1 = closure->data;
-      data2 = g_value_peek_pointer (param_values + 0);
-    }
-  else
-    {
-      data1 = g_value_peek_pointer (param_values + 0);
-      data2 = closure->data;
-    }
-  callback = (GMarshalFunc_VOID__STRING_STRING_POINTER_UCHAR_UINT) (marshal_data ? marshal_data : cc->callback);
-
-  callback (data1,
-            g_marshal_value_peek_string (param_values + 1),
-            g_marshal_value_peek_string (param_values + 2),
-            g_marshal_value_peek_pointer (param_values + 3),
-            g_marshal_value_peek_uchar (param_values + 4),
-            g_marshal_value_peek_uint (param_values + 5),
-            data2);
-}
-
-G_END_DECLS
-
-#endif /* __g_cclosure_user_marshal_MARSHAL_H__ */
-
-
-/****************************************************************************
- * ABOVE: MARSHALLERS *******************************************************
- ****************************************************************************/
-
-
-/****************************************************************************
- * BELOW: TYPEDEFS **********************************************************
- ****************************************************************************/
-
-/** This enumerated type defines the possible connection states. */
-typedef enum
-{
-    /** The receiver is "off", meaning that either the bluetooth radio is
-     * off or the user has requested not to connect to the GPS receiver.
-     * No gtk_banner is visible. */
-    RCVR_OFF,
-
-    /** The connection with the receiver is down.  A gtk_banner is visible with
-     * the text, "Connecting to GPS receiver". */
-    RCVR_DOWN,
-
-    /** The connection with the receiver is up, but a GPS fix is not available.
-     * A gtk_banner is visible with the text, "(Re-)Establishing GPS fix". */
-    RCVR_UP,
-
-    /** The connection with the receiver is up and a GPS fix IS available.
-     * No gtk_banner is visible. */
-    RCVR_FIXED
-} ConnState;
-
-/** This enumerated type defines the supported types of repositories. */
-typedef enum
-{
-    REPOTYPE_NONE, /* No URL set. */
-    REPOTYPE_XYZ, /* x=%d, y=%d, and zoom=%d */
-    REPOTYPE_XYZ_INV, /* zoom=%0d, x=%d, y=%d */
-    REPOTYPE_QUAD_QRST, /* t=%s   (%s = {qrst}*) */
-    REPOTYPE_QUAD_ZERO, /* t=%0s  (%0s = {0123}*) */
-    REPOTYPE_WMS        /* "service=wms" */
-} RepoType;
-
-/** Possible center modes.  The "WAS" modes imply no current center mode;
- * they only hint at what the last center mode was, so that it can be
- * recalled. */
-typedef enum
-{
-    CENTER_WAS_LATLON = -2,
-    CENTER_WAS_LEAD = -1,
-    CENTER_LEAD = 1,
-    CENTER_LATLON = 2
-} CenterMode;
-
-/** This enum defines the states of the SAX parsing state machine. */
-typedef enum
-{
-    START,
-    INSIDE_GPX,
-    INSIDE_PATH,
-    INSIDE_PATH_SEGMENT,
-    INSIDE_PATH_POINT,
-    INSIDE_PATH_POINT_ELE,
-    INSIDE_PATH_POINT_TIME,
-    INSIDE_PATH_POINT_DESC,
-    FINISH,
-    UNKNOWN,
-    ERROR,
-} SaxState;
-
-/** POI dialog action **/
-typedef enum
-{
-    ACTION_ADD_POI,
-    ACTION_EDIT_POI,
-} POIAction;
-
-/** Category list **/
-typedef enum
-{
-    CAT_ID,
-    CAT_ENABLED,
-    CAT_LABEL,
-    CAT_DESC,
-    CAT_POI_CNT,
-    CAT_NUM_COLUMNS
-} CategoryList;
-
-/** POI list **/
-typedef enum
-{
-    POI_POIID,
-    POI_CATID,
-    POI_LAT,
-    POI_LON,
-    POI_LATLON,
-    POI_LABEL,
-    POI_DESC,
-    POI_CATLAB,
-    POI_NUM_COLUMNS
-} POIList;
-
-/** This enum defines the possible units we can use. */
-typedef enum
-{
-    UNITS_KM,
-    UNITS_MI,
-    UNITS_NM,
-    UNITS_ENUM_COUNT
-} UnitType;
-gchar *UNITS_TEXT[UNITS_ENUM_COUNT];
-
-/* UNITS_CONVERTS, when multiplied, converts from NM. */
-#define EARTH_RADIUS (3440.06479f)
-gfloat UNITS_CONVERT[] =
-{
-    1.85200,
-    1.15077945,
-    1.f,
-};
-
-/** This enum defines the possible font sizes. */
-typedef enum
-{
-    INFO_FONT_XXSMALL,
-    INFO_FONT_XSMALL,
-    INFO_FONT_SMALL,
-    INFO_FONT_MEDIUM,
-    INFO_FONT_LARGE,
-    INFO_FONT_XLARGE,
-    INFO_FONT_XXLARGE,
-    INFO_FONT_ENUM_COUNT
-} InfoFontSize;
-gchar *INFO_FONT_TEXT[INFO_FONT_ENUM_COUNT];
-
-/** This enum defines all of the key-customizable actions. */
-typedef enum
-{
-    CUSTOM_ACTION_PAN_NORTH,
-    CUSTOM_ACTION_PAN_WEST,
-    CUSTOM_ACTION_PAN_SOUTH,
-    CUSTOM_ACTION_PAN_EAST,
-    CUSTOM_ACTION_TOGGLE_AUTOCENTER,
-    CUSTOM_ACTION_ZOOM_IN,
-    CUSTOM_ACTION_ZOOM_OUT,
-    CUSTOM_ACTION_TOGGLE_FULLSCREEN,
-    CUSTOM_ACTION_TOGGLE_TRACKS,
-    CUSTOM_ACTION_TOGGLE_SCALE,
-    CUSTOM_ACTION_TOGGLE_POI,
-    CUSTOM_ACTION_CHANGE_REPO,
-    CUSTOM_ACTION_ROUTE_DISTNEXT,
-    CUSTOM_ACTION_ROUTE_DISTLAST,
-    CUSTOM_ACTION_TRACK_BREAK,
-    CUSTOM_ACTION_TRACK_CLEAR,
-    CUSTOM_ACTION_TRACK_DISTLAST,
-    CUSTOM_ACTION_TRACK_DISTFIRST,
-    CUSTOM_ACTION_TOGGLE_GPS,
-    CUSTOM_ACTION_TOGGLE_GPSINFO,
-    CUSTOM_ACTION_TOGGLE_SPEEDLIMIT,
-    CUSTOM_ACTION_RESET_BLUETOOTH,
-    CUSTOM_ACTION_ENUM_COUNT
-} CustomAction;
-gchar *CUSTOM_ACTION_TEXT[CUSTOM_ACTION_ENUM_COUNT];
-
-/** This enum defines all of the customizable keys. */
-typedef enum
-{
-    CUSTOM_KEY_UP,
-    CUSTOM_KEY_LEFT,
-    CUSTOM_KEY_DOWN,
-    CUSTOM_KEY_RIGHT,
-    CUSTOM_KEY_SELECT,
-    CUSTOM_KEY_INCREASE,
-    CUSTOM_KEY_DECREASE,
-    CUSTOM_KEY_FULLSCREEN,
-    CUSTOM_KEY_ESC,
-    CUSTOM_KEY_ENUM_COUNT
-} CustomKey;
-gchar *CUSTOM_KEY_GCONF[CUSTOM_KEY_ENUM_COUNT];
-gchar *CUSTOM_KEY_ICON[CUSTOM_KEY_ENUM_COUNT];
-CustomAction CUSTOM_KEY_DEFAULT[CUSTOM_KEY_ENUM_COUNT];
-
-/** This enum defines all of the colorable objects. */
-typedef enum
-{
-    COLORABLE_MARK,
-    COLORABLE_MARK_VELOCITY,
-    COLORABLE_MARK_OLD,
-    COLORABLE_TRACK,
-    COLORABLE_TRACK_MARK,
-    COLORABLE_TRACK_BREAK,
-    COLORABLE_ROUTE,
-    COLORABLE_ROUTE_WAY,
-    COLORABLE_ROUTE_BREAK,
-    COLORABLE_POI,
-    COLORABLE_ENUM_COUNT
-} Colorable;
-gchar *COLORABLE_GCONF[COLORABLE_ENUM_COUNT];
-GdkColor COLORABLE_DEFAULT[COLORABLE_ENUM_COUNT] = {
-    {0, 0x0000, 0x0000, 0xc000}, /* COLORABLE_MARK */
-    {0, 0x6000, 0x6000, 0xf800}, /* COLORABLE_MARK_VELOCITY */
-    {0, 0x8000, 0x8000, 0x8000}, /* COLORABLE_MARK_OLD */
-    {0, 0xe000, 0x0000, 0x0000}, /* COLORABLE_TRACK */
-    {0, 0xa000, 0x0000, 0x0000}, /* COLORABLE_TRACK_MARK */
-    {0, 0x7000, 0x0000, 0x0000}, /* COLORABLE_TRACK_BREAK */
-    {0, 0x0000, 0xa000, 0x0000}, /* COLORABLE_ROUTE */
-    {0, 0x0000, 0x8000, 0x0000}, /* COLORABLE_ROUTE_WAY */
-    {0, 0x0000, 0x6000, 0x0000}, /* COLORABLE_ROUTE_BREAK */
-    {0, 0xa000, 0x0000, 0xa000}  /* COLORABLE_POI */
-};
-
-typedef enum
-{
-    DDPDDDDD,
-    DD_MMPMMM,
-    DD_MM_SSPS,
-    DDPDDDDD_NSEW,
-    DD_MMPMMM_NSEW,
-    DD_MM_SSPS_NSEW,
-    NSEW_DDPDDDDD,
-    NSEW_DD_MMPMMM,
-    NSEW_DD_MM_SSPS,
-    DEG_FORMAT_ENUM_COUNT
-} DegFormat;
-gchar *DEG_FORMAT_TEXT[DEG_FORMAT_ENUM_COUNT];
-
-typedef enum
-{
-    SPEED_LOCATION_TOP_LEFT,
-    SPEED_LOCATION_TOP_RIGHT,
-    SPEED_LOCATION_BOTTOM_RIGHT,
-    SPEED_LOCATION_BOTTOM_LEFT,
-    SPEED_LOCATION_ENUM_COUNT
-} SpeedLocation;
-gchar *SPEED_LOCATION_TEXT[SPEED_LOCATION_ENUM_COUNT];
-
-/** A general definition of a point in the Maemo Mapper unit system. */
-typedef struct _Point Point;
-struct _Point {
-    guint unitx;
-    guint unity;
-    time_t time;
-    gfloat altitude;
-};
-
-/** A WayPoint, which is a Point with a description. */
-typedef struct _WayPoint WayPoint;
-struct _WayPoint {
-    Point *point;
-    gchar *desc;
-};
-
-/** A Path is a set of PathPoints and WayPoints. */
-typedef struct _Path Path;
-struct _Path {
-    Point *head; /* points to first element in array; NULL if empty. */
-    Point *tail; /* points to last element in array. */
-    Point *cap; /* points after last slot in array. */
-    WayPoint *whead; /* points to first element in array; NULL if empty. */
-    WayPoint *wtail; /* points to last element in array. */
-    WayPoint *wcap; /* points after last slot in array. */
-};
-
-/** Data used during the SAX parsing operation. */
-typedef struct _SaxData SaxData;
-struct _SaxData {
-    Path path;
-    SaxState state;
-    SaxState prev_state;
-    guint unknown_depth;
-    gboolean at_least_one_trkpt;
-    GString *chars;
-};
-
-/** Data used during action: add or edit category/poi **/
-typedef struct _DeletePOI DeletePOI;
-struct _DeletePOI {
-    GtkWidget *dialog;
-    gchar *txt_label;
-    guint id;
-};
-
-/** Data regarding a map repository. */
-typedef struct _RepoData RepoData;
-struct _RepoData {
-    gchar *name;
-    gchar *url;
-    gchar *cache_dir;
-    guint dl_zoom_steps;
-    guint view_zoom_steps;
-    gboolean double_size;
-    gboolean nextable;
-    RepoType type;
-    GtkWidget *menu_item;
-};
-
-/** GPS Data and Satellite **/
-typedef struct _GpsData GpsData;
-struct _GpsData {
-    guint fix;
-    guint fixquality;
-    gfloat lat;
-    gfloat lon;
-    gfloat speed;    /* in knots */
-    gfloat maxspeed;    /* in knots */
-    gfloat heading;
-    gfloat hdop;
-    gfloat pdop;
-    gfloat vdop;
-    guint satinview;
-    guint satinuse;
-    guint satforfix[12];
-};
-
-typedef struct _GpsSatelliteData GpsSatelliteData;
-struct _GpsSatelliteData {
-    guint prn;
-    guint elevation;
-    guint azimuth;
-    guint snr;
-};
-
-/** Data used during the asynchronous progress update phase of automatic map
- * downloading. */
-typedef struct _ProgressUpdateInfo ProgressUpdateInfo;
-struct _ProgressUpdateInfo
-{
-    gchar *src_str;
-    gchar *dest_str;
-    RepoData *repo;
-    guint tilex, tiley, zoom; /* for refresh. */
-    gint retries; /* if equal to zero, it means we're DELETING maps. */
-    guint priority;
-    FILE *file;
-};
-
-typedef struct _RouteDownloadData RouteDownloadData;
-struct _RouteDownloadData {
-    gchar *bytes;
-    guint bytes_read;
-};
-
-/** Data used during the asynchronous automatic route downloading operation. */
-typedef struct _AutoRouteDownloadData AutoRouteDownloadData;
-struct _AutoRouteDownloadData {
-    gboolean enabled;
-    gboolean in_progress;
-    gchar *dest;
-    CURL *curl_easy;
-    gchar *src_str;
-    RouteDownloadData rdl_data;
-};
-
-/** Data to describe a POI. */
-typedef struct _PoiInfo PoiInfo;
-struct _PoiInfo {
-    guint poi_id;
-    guint cat_id;
-    gfloat lat;
-    gfloat lon;
-    gchar *label;
-    gchar *desc;
-    gchar *clabel;
-};
-
-/****************************************************************************
- * ABOVE: TYPEDEFS **********************************************************
- ****************************************************************************/
-
-/****************************************************************************
- * BELOW: DATA **************************************************************
- ****************************************************************************/
-
-/** The main GtkWindow of the application. */
-static HildonProgram *_program = NULL;
-
-/** The main GtkContainer of the application. */
-static GtkWidget *_window = NULL;
-
-/** The main OSSO context of the application. */
-static osso_context_t *_osso = NULL;
-
-/** The widget that provides the visual display of the map. */
-static GtkWidget *_map_widget = NULL;
-
-/** The backing pixmap of _map_widget. */
-static GdkPixmap *_map_pixmap = NULL;
-
-static GtkWidget *_gps_widget = NULL;
-static GtkWidget *_text_lat = NULL;
-static GtkWidget *_text_lon = NULL;
-static GtkWidget *_text_speed = NULL;
-static GtkWidget *_text_alt = NULL;
-static GtkWidget *_sat_panel = NULL;
-static GtkWidget *_text_time = NULL;
-static GtkWidget *_heading_panel = NULL;
-
-static GtkWidget *_sat_details_panel = NULL;
-static GtkWidget *_sdi_lat = NULL;
-static GtkWidget *_sdi_lon = NULL;
-static GtkWidget *_sdi_spd = NULL;
-static GtkWidget *_sdi_alt = NULL;
-static GtkWidget *_sdi_hea = NULL;
-static GtkWidget *_sdi_tim = NULL;
-static GtkWidget *_sdi_vie = NULL;
-static GtkWidget *_sdi_use = NULL;
-static GtkWidget *_sdi_fix = NULL;
-static GtkWidget *_sdi_fqu = NULL;
-static GtkWidget *_sdi_msp = NULL;
-
-/** The file descriptor of our connection with the GPS receiver. */
-static gint _fd = -1;
-#define GPS_READ_BUF_SIZE 256
-static gchar _gps_read_buf[GPS_READ_BUF_SIZE];
-static gchar *_gps_read_buf_curr = _gps_read_buf;
-static gchar *_gps_read_buf_last = _gps_read_buf + GPS_READ_BUF_SIZE - 1;
-static DBusGProxy *_rfcomm_req_proxy = NULL;
-
-/** The GIOChannel through which communication with the GPS receiver is
- * performed. */
-static GIOChannel *_channel = NULL;
-
-/** The Source ID of the connect watch. */
-static guint _connect_sid = 0;
-/** The Source ID of the error watch. */
-static guint _error_sid = 0;
-/** The Source ID of the input watch. */
-static guint _input_sid = 0;
-/** The Source ID of the "Connect Later" idle. */
-static guint _clater_sid = 0;
-/** The Source ID of the CURL Multi Download timeout. */
-static guint _curl_sid = 0;
-
-/** GPS data. */
-static Point _pos = { 0, 0, 0, NAN};
-static const Point _point_null = { 0, 0, 0, NAN};
-static gint _vel_offsetx = 0;
-static gint _vel_offsety = 0;
-
-static GpsData _gps;
-static GpsSatelliteData _gps_sat[12];
-gboolean _satdetails_on = FALSE;
-
-/** The current connection state. */
-static ConnState _conn_state = RCVR_OFF;
-
-/** VARIABLES PERTAINING TO THE INTERNET CONNECTION. */
-static gboolean _iap_connected = FALSE;
-static gboolean _iap_connecting = FALSE;
-static gchar *_iap_http_proxy_host = NULL;
-static gint _iap_http_proxy_port = 0;
-
-/** VARIABLES FOR MAINTAINING STATE OF THE CURRENT VIEW. */
-
-/** The "zoom" level defines the resolution of a pixel, from 0 to MAX_ZOOM.
- * Each pixel in the current view is exactly (1 << _zoom) "units" wide. */
-static guint _zoom = 3; /* zoom level, from 0 to MAX_ZOOM. */
-static Point _center = {-1, -1}; /* current center location, X. */
-
-/** The "base tile" is the upper-left tile in the pixmap. */
-static guint _base_tilex = -5;
-static guint _base_tiley = -5;
-
-/** The "offset" defines the upper-left corner of the visible portion of the
- * 1024x768 pixmap. */
-static guint _offsetx = -1;
-static guint _offsety = -1;
-
-
-/** CACHED SCREEN INFORMATION THAT IS DEPENDENT ON THE CURRENT VIEW. */
-static guint _screen_grids_halfwidth = 0;
-static guint _screen_grids_halfheight = 0;
-static guint _screen_width_pixels = 0;
-static guint _screen_height_pixels = 0;
-static Point _focus = {-1, -1};
-static guint _focus_unitwidth = 0;
-static guint _focus_unitheight = 0;
-static Point _min_center = {-1, -1};
-static Point _max_center = {-1, -1};
-static guint _world_size_tiles = -1;
-
-
-/** VARIABLES FOR ACCESSING THE LOCATION/BOUNDS OF THE CURRENT MARK. */
-static gint _mark_x1 = -1;
-static gint _mark_x2 = -1;
-static gint _mark_y1 = -1;
-static gint _mark_y2 = -1;
-static gint _mark_minx = -1;
-static gint _mark_miny = -1;
-static gint _mark_width = -1;
-static gint _mark_height = -1;
-
-/** Pango stuff. */
-static GdkRectangle _scale_rect;
-static GdkRectangle _zoom_rect;
-static PangoContext *_scale_context = NULL;
-static PangoContext *_zoom_context = NULL;
-static PangoFontDescription *_scale_font = NULL;
-static PangoFontDescription *_zoom_font = NULL;
-static PangoLayout *_scale_layout = NULL;
-static PangoLayout *_zoom_layout = NULL;
-static GdkGC *_speed_limit_gc1 = NULL;
-static GdkGC *_speed_limit_gc2 = NULL;
-static PangoContext *_speed_limit_context = NULL;
-static PangoLayout *_speed_limit_layout = NULL;
-static PangoFontDescription *_speed_limit_fontdesc = NULL;
-static PangoContext *_sat_panel_context = NULL;
-static PangoLayout *_sat_panel_layout = NULL;
-static PangoFontDescription *_sat_panel_fontdesc = NULL;
-static PangoContext *_heading_panel_context = NULL;
-static PangoLayout *_heading_panel_layout = NULL;
-static PangoFontDescription *_heading_panel_fontdesc = NULL;
-static GdkGC *_sat_info_gc1 = NULL;
-static GdkGC *_sat_info_gc2 = NULL;
-static PangoContext *_sat_info_context = NULL;
-static PangoLayout *_sat_info_layout = NULL;
-static PangoFontDescription *_sat_info_fontdesc = NULL;
-static PangoContext *_sat_details_context = NULL;
-static PangoLayout *_sat_details_layout = NULL;
-static PangoFontDescription *_sat_details_fontdesc = NULL;
-static PangoContext *_sat_details_expose_context = NULL;
-static PangoLayout *_sat_details_expose_layout = NULL;
-static PangoFontDescription *_sat_details_expose_fontdesc = NULL;
-#define SCALE_WIDTH (100)
-
-/** The current track and route. */
-static Path _track;
-static Path _route;
-
-/** Data for tracking waypoints for the purpose of announcement. */
-/* _near_point is the route point to which we are closest. */
-static Point *_near_point = NULL;
-static guint64 _near_point_dist_squared = -1;
-/* _next_way is what we currently interpret to be the next waypoint. */
-static WayPoint *_next_way = NULL;
-static guint64 _next_way_dist_squared = -1;
-static gchar *_last_spoken_phrase = NULL;
-/* _next_wpt is the route point immediately following _next_way. */
-static Point *_next_wpt = NULL;
-static guint64 _next_wpt_dist_squared = -1;
-
-static guint _key_zoom_new = 0;
-static guint _key_zoom_timeout_sid = 0;
-
-/** THE GdkGC OBJECTS USED FOR DRAWING. */
-static GdkGC *_gc[COLORABLE_ENUM_COUNT];
-static GdkColor _color[COLORABLE_ENUM_COUNT];
-
-/* Menu items for the "Route" submenu. */
-static GtkWidget *_menu_route_download_item = NULL;
-static GtkWidget *_menu_route_open_item = NULL;
-static GtkWidget *_menu_route_save_item = NULL;
-static GtkWidget *_menu_route_distnext_item = NULL;
-static GtkWidget *_menu_route_distlast_item = NULL;
-static GtkWidget *_menu_route_reset_item = NULL;
-static GtkWidget *_menu_route_clear_item = NULL;
-
-/* Menu items for the "Track" submenu. */
-static GtkWidget *_menu_track_open_item = NULL;
-static GtkWidget *_menu_track_save_item = NULL;
-static GtkWidget *_menu_track_insert_break_item = NULL;
-static GtkWidget *_menu_track_insert_mark_item = NULL;
-static GtkWidget *_menu_track_distlast_item = NULL;
-static GtkWidget *_menu_track_distfirst_item = NULL;
-static GtkWidget *_menu_track_clear_item = NULL;
-
-/* Menu items for the "Maps" submenu. */
-static GtkWidget *_menu_maps_submenu = NULL;
-static GtkWidget *_menu_maps_mapman_item = NULL;
-static GtkWidget *_menu_maps_repoman_item = NULL;
-static GtkWidget *_menu_auto_download_item = NULL;
-
-/* Menu items for the "View" submenu. */
-static GtkWidget *_menu_zoomin_item = NULL;
-static GtkWidget *_menu_zoomout_item = NULL;
-static GtkWidget *_menu_fullscreen_item = NULL;
-static GtkWidget *_menu_show_zoomlevel_item = NULL;
-static GtkWidget *_menu_show_scale_item = NULL;
-static GtkWidget *_menu_show_routes_item = NULL;
-static GtkWidget *_menu_show_tracks_item = NULL;
-static GtkWidget *_menu_show_velvec_item = NULL;
-static GtkWidget *_menu_show_poi_item = NULL;
-static GtkWidget *_menu_poi_item = NULL;
-
-/* Menu items for the "Auto-Center" submenu. */
-static GtkWidget *_menu_ac_latlon_item = NULL;
-static GtkWidget *_menu_ac_lead_item = NULL;
-static GtkWidget *_menu_ac_none_item = NULL;
-
-/* Menu items for the "Go to" submenu. */
-static GtkWidget *_menu_goto_latlon = NULL;
-static GtkWidget *_menu_goto_address = NULL;
-static GtkWidget *_menu_goto_gps = NULL;
-static GtkWidget *_menu_goto_nextway = NULL;
-static GtkWidget *_menu_goto_nearpoi = NULL;
-
-/* Menu items for the "GPS" submenu. */
-static GtkWidget *_menu_enable_gps_item = NULL;
-static GtkWidget *_menu_gps_show_info_item = NULL;
-static GtkWidget *_menu_gps_details_item = NULL;
-static GtkWidget *_menu_gps_reset_item = NULL;
-
-/* Menu items for the other menu items. */
-static GtkWidget *_menu_settings_item = NULL;
-static GtkWidget *_menu_help_item = NULL;
-static GtkWidget *_menu_about_item = NULL;
-static GtkWidget *_menu_close_item = NULL;
-
-/** CONTEXT MENU ITEMS. */
-static guint _cmenu_position_x;
-static guint _cmenu_position_y;
-
-/* Menu items for the "Location" context menu. */
-static GtkWidget *_cmenu_loc_show_latlon_item = NULL;
-static GtkWidget *_cmenu_loc_route_to_item = NULL;
-static GtkWidget *_cmenu_loc_distance_to_item = NULL;
-static GtkWidget *_cmenu_loc_add_route = NULL;
-static GtkWidget *_cmenu_loc_add_way = NULL;
-static GtkWidget *_cmenu_loc_add_poi = NULL;
-static GtkWidget *_cmenu_loc_set_gps = NULL;
-
-/* Menu items for the "Waypoint" context menu. */
-static GtkWidget *_cmenu_way_show_latlon_item = NULL;
-static GtkWidget *_cmenu_way_show_desc_item = NULL;
-static GtkWidget *_cmenu_way_clip_latlon_item = NULL;
-static GtkWidget *_cmenu_way_clip_desc_item = NULL;
-static GtkWidget *_cmenu_way_route_to_item = NULL;
-static GtkWidget *_cmenu_way_distance_to_item = NULL;
-static GtkWidget *_cmenu_way_delete_item = NULL;
-static GtkWidget *_cmenu_way_add_poi = NULL;
-static GtkWidget *_cmenu_way_goto_nextway = NULL;
-
-/* Menu items for the "POI" context menu. */
-static GtkWidget *_cmenu_poi = NULL;
-static GtkWidget *_cmenu_poi_edit_poi = NULL;
-static GtkWidget *_cmenu_poi_route_to_item = NULL;
-static GtkWidget *_cmenu_poi_distance_to_item = NULL;
-static GtkWidget *_cmenu_poi_add_route = NULL;
-static GtkWidget *_cmenu_poi_add_way = NULL;
-static GtkWidget *_cmenu_poi_goto_nearpoi = NULL;
-
-/** BANNERS. */
-GtkWidget *_connect_banner = NULL;
-GtkWidget *_fix_banner = NULL;
-GtkWidget *_download_banner = NULL;
-
-/** DOWNLOAD PROGRESS. */
-static CURLM *_curl_multi = NULL;
-static GQueue *_curl_easy_queue = NULL;
-static guint _num_downloads = 0;
-static guint _curr_download = 0;
-static GTree *_pui_tree = NULL;
-static GTree *_downloading_tree = NULL;
-static GHashTable *_pui_by_easy = NULL;
-
-/** CONFIGURATION INFORMATION. */
-static gchar *_rcvr_mac = NULL;
-static gchar *_route_dir_uri = NULL;
-static gchar *_track_file_uri = NULL;
-static CenterMode _center_mode = CENTER_LEAD;
-static gboolean _fullscreen = FALSE;
-static gboolean _enable_gps = FALSE;
-static gboolean _gps_info = FALSE;
-static gchar *_route_dl_url = NULL;
-static guint _route_dl_radius = 4;
-static gint _show_tracks = 0;
-static gboolean _show_zoomlevel = TRUE;
-static gboolean _show_scale = TRUE;
-static gboolean _show_velvec = TRUE;
-static gboolean _show_poi = TRUE;
-static gboolean _auto_download = FALSE;
-static guint _lead_ratio = 5;
-static guint _center_ratio = 7;
-static guint _draw_width = 5;
-static guint _announce_notice_ratio = 8;
-static gboolean _enable_voice = TRUE;
-static gboolean _always_keep_on = FALSE;
-static gdouble _voice_speed = 1.0;
-static gint _voice_pitch = 0;
-static GSList *_loc_list;
-static GtkListStore *_loc_model;
-static UnitType _units = UNITS_KM;
-static CustomAction _action[CUSTOM_KEY_ENUM_COUNT];
-static guint _degformat = DDPDDDDD;
-static gboolean _speed_limit_on = FALSE;
-static guint _speed_limit = 100;
-static gboolean _speed_excess = FALSE;
-static SpeedLocation _speed_location = SPEED_LOCATION_TOP_RIGHT;
-static InfoFontSize _info_font_size = INFO_FONT_MEDIUM;
-
-static GList *_repo_list = NULL;
-static RepoData *_curr_repo = NULL;
-
-/** POI */
-static gchar *_poi_db = NULL;
-static sqlite3 *_db = NULL;
-static guint _poi_zoom = 6;
-
-static sqlite3_stmt *_stmt_select_poi = NULL;
-static sqlite3_stmt *_stmt_select_nearest_poi = NULL;
-static sqlite3_stmt *_stmt_insert_poi = NULL;
-static sqlite3_stmt *_stmt_update_poi = NULL;
-static sqlite3_stmt *_stmt_delete_poi = NULL;
-static sqlite3_stmt *_stmt_delete_poi_by_catid = NULL;
-static sqlite3_stmt *_stmt_nextlabel_poi = NULL;
-
-static sqlite3_stmt *_stmt_select_cat = NULL;
-static sqlite3_stmt *_stmt_insert_cat = NULL;
-static sqlite3_stmt *_stmt_update_cat = NULL;
-static sqlite3_stmt *_stmt_delete_cat = NULL;
-static sqlite3_stmt *_stmt_toggle_cat = NULL;
-static sqlite3_stmt *_stmt_selall_cat = NULL;
-
-/** The singleton auto-route-download data. */
-static AutoRouteDownloadData _autoroute_data;
-
-static gchar XML_TZONE[7];
-static gint _gmtoffset = 0;
-
-/****************************************************************************
- * ABOVE: DATA **************************************************************
- ****************************************************************************/
-
-
-
-/****************************************************************************
- * BELOW: CALLBACK DECLARATIONS *********************************************
- ****************************************************************************/
-
-static gint
-dbus_cb_default(const gchar *interface, const gchar *method,
-        GArray *arguments, gpointer data, osso_rpc_t *retval);
-static void
-osso_cb_hw_state(osso_hw_state_t *state, gpointer data);
-static gboolean
-window_cb_key_press(GtkWidget* widget, GdkEventKey *event);
-static gboolean
-window_cb_key_release(GtkWidget* widget, GdkEventKey *event);
-
-void
-map_force_redraw(void);
-static gboolean
-map_cb_configure(GtkWidget *widget, GdkEventConfigure *event);
-static gboolean
-map_cb_expose(GtkWidget *widget, GdkEventExpose *event);
-static gboolean
-map_cb_button_press(GtkWidget *widget, GdkEventButton *event);
-static gboolean
-map_cb_button_release(GtkWidget *widget, GdkEventButton *event);
-static gboolean
-heading_panel_expose(GtkWidget *widget, GdkEventExpose *event);
-static gboolean
-sat_panel_expose(GtkWidget *widget, GdkEventExpose *event);
-static gboolean
-sat_details_panel_expose(GtkWidget *widget, GdkEventExpose *event);
-
-static gboolean
-channel_cb_error(GIOChannel *src, GIOCondition condition, gpointer data);
-static gboolean
-channel_cb_connect(GIOChannel *src, GIOCondition condition, gpointer data);
-static gboolean
-channel_cb_input(GIOChannel *src, GIOCondition condition, gpointer data);
-
-/* Callbacks for the "Route" submenu. */
-static gboolean
-menu_cb_route_download(GtkAction *action);
-static gboolean
-menu_cb_route_open(GtkAction *action);
-static gboolean
-menu_cb_route_save(GtkAction *action);
-static gboolean
-menu_cb_route_distnext(GtkAction *action);
-static gboolean
-menu_cb_route_distlast(GtkAction *action);
-static gboolean
-menu_cb_route_reset(GtkAction *action);
-static gboolean
-menu_cb_route_clear(GtkAction *action);
-
-/* Callbacks for the "Track" submenu. */
-static gboolean
-menu_cb_track_open(GtkAction *action);
-static gboolean
-menu_cb_track_save(GtkAction *action);
-static gboolean
-menu_cb_track_insert_break(GtkAction *action);
-static gboolean
-menu_cb_track_insert_mark(GtkAction *action);
-static gboolean
-menu_cb_track_distlast(GtkAction *action);
-static gboolean
-menu_cb_track_distfirst(GtkAction *action);
-static gboolean
-menu_cb_track_clear(GtkAction *action);
-
-/* Callbacks for the "Maps" submenu. */
-static gboolean
-menu_cb_maps_select(GtkAction *action, gpointer new_repo);
-static gboolean
-menu_cb_mapman(GtkAction *action);
-static gboolean
-repoman_dialog();
-static gboolean
-menu_cb_maps_repoman(GtkAction *action);
-static gboolean
-menu_cb_auto_download(GtkAction *action);
-
-/* Callbacks for the "View" submenu. */
-static gboolean
-menu_cb_zoomin(GtkAction *action);
-static gboolean
-menu_cb_zoomout(GtkAction *action);
-static gboolean
-menu_cb_fullscreen(GtkAction *action);
-static gboolean
-menu_cb_show_zoomlevel(GtkAction *action);
-static gboolean
-menu_cb_show_scale(GtkAction *action);
-static gboolean
-menu_cb_show_routes(GtkAction *action);
-static gboolean
-menu_cb_show_tracks(GtkAction *action);
-static gboolean
-menu_cb_show_velvec(GtkAction *action);
-static gboolean
-menu_cb_show_poi(GtkAction *action);
-static gboolean
-menu_cb_category(GtkAction *action);
-
-/* Callbacks for the "Auto-Center" submenu. */
-static gboolean
-menu_cb_ac_latlon(GtkAction *action);
-static gboolean
-menu_cb_ac_lead(GtkAction *action);
-static gboolean
-menu_cb_ac_none(GtkAction *action);
-
-/* Callbacks for the "Go to" submenu. */
-static gboolean
-menu_cb_goto_latlon(GtkAction *action);
-static gboolean
-menu_cb_goto_address(GtkAction *action);
-static gboolean
-menu_cb_goto_gps(GtkAction *action);
-static gboolean
-menu_cb_goto_nextway(GtkAction *action);
-static gboolean
-menu_cb_goto_nearpoi(GtkAction *action);
-
-/* Callbacks for the "GPS" submenu. */
-static gboolean
-menu_cb_enable_gps(GtkAction *action);
-static gboolean
-menu_cb_gps_show_info(GtkAction *action);
-static gboolean
-menu_cb_gps_details(GtkAction *action);
-static gboolean
-menu_cb_gps_reset(GtkAction *action);
-
-/* Callbacks for the other menu items. */
-static gboolean
-menu_cb_settings(GtkAction *action);
-static gboolean
-menu_cb_help(GtkAction *action);
-static gboolean
-menu_cb_about(GtkAction *action);
-
-
-/* Callbacks for the "Location" context menu. */
-static gboolean
-cmenu_cb_loc_show_latlon(GtkAction *action);
-static gboolean
-cmenu_cb_loc_route_to(GtkAction *action);
-static gboolean
-cmenu_cb_loc_distance_to(GtkAction *action);
-static gboolean
-cmenu_cb_loc_add_route(GtkAction *action);
-static gboolean
-cmenu_cb_loc_add_way(GtkAction *action);
-static gboolean
-cmenu_cb_loc_add_poi(GtkAction *action);
-static gboolean
-cmenu_cb_loc_set_gps(GtkAction *action);
-
-/* Callbacks for the "Waypoint" context menu. */
-static gboolean
-cmenu_cb_way_show_latlon(GtkAction *action);
-static gboolean
-cmenu_cb_way_show_desc(GtkAction *action);
-static gboolean
-cmenu_cb_way_clip_latlon(GtkAction *action);
-static gboolean
-cmenu_cb_way_clip_desc(GtkAction *action);
-static gboolean
-cmenu_cb_way_route_to(GtkAction *action);
-static gboolean
-cmenu_cb_way_distance_to(GtkAction *action);
-static gboolean
-cmenu_cb_way_delete(GtkAction *action);
-static gboolean
-cmenu_cb_way_add_poi(GtkAction *action);
-
-/* Callbacks for the "POI" context menu. */
-static gboolean
-cmenu_cb_poi_route_to(GtkAction *action);
-static gboolean
-cmenu_cb_poi_distance_to(GtkAction *action);
-static gboolean
-cmenu_cb_poi_edit_poi(GtkAction *action);
-static gboolean
-cmenu_cb_poi_add_route(GtkAction *action);
-static gboolean
-cmenu_cb_poi_add_way(GtkAction *action);
-
-
-static gboolean
-curl_download_timeout();
-
-static gboolean
-auto_route_dl_idle();
-
-static gint
-strdmstod_1(gdouble *d,gchar *nptr, gchar **endptr, gchar *sep, gint utf8_deg);
-static gdouble
-strdmstod_2(gchar *nptr, gchar **endptr);
-static gdouble
-strdmstod(const gchar *nptr, gchar **endptr);
-
-/****************************************************************************
- * ABOVE: CALLBACK DECLARATIONS *********************************************
- ****************************************************************************/
-
-/**
- * Pop up a modal dialog box with simple error information in it.
- */
-static void
-popup_error(GtkWidget *window, const gchar *error)
-{
-    GtkWidget *dialog;
-    printf("%s(\"%s\")\n", __PRETTY_FUNCTION__, error);
-
-    dialog = hildon_note_new_information(GTK_WINDOW(window), error);
-
-    gtk_dialog_run(GTK_DIALOG(dialog));
-    gtk_widget_destroy(dialog);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static void
-path_resize(Path *path, guint size)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(path->head + size != path->cap)
-    {
-        Point *old_head = path->head;
-        WayPoint *curr;
-        path->head = g_renew(Point, old_head, size);
-        path->cap = path->head + size;
-        if(path->head != old_head)
-        {
-            path->tail = path->head + (path->tail - old_head);
-
-            /* Adjust all of the waypoints. */
-            for(curr = path->whead - 1; curr++ != path->wtail; )
-                curr->point = path->head + (curr->point - old_head);
-        }
-    }
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static void
-path_wresize(Path *path, guint wsize)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(path->whead + wsize != path->wcap)
-    {
-        WayPoint *old_whead = path->whead;
-        path->whead = g_renew(WayPoint, old_whead, wsize);
-        path->wtail = path->whead + (path->wtail - old_whead);
-        path->wcap = path->whead + wsize;
-    }
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-
-/****************************************************************************
- * BELOW: FILE-HANDLING ROUTINES *********************************************
- ****************************************************************************/
-
-#define WRITE_STRING(string) { \
-    GnomeVFSResult vfs_result; \
-    GnomeVFSFileSize size; \
-    if(GNOME_VFS_OK != (vfs_result = gnome_vfs_write( \
-                    handle, (string), strlen((string)), &size))) \
-    { \
-        gchar buffer[BUFFER_SIZE]; \
-        snprintf(buffer, sizeof(buffer), \
-                "%s:\n%s\n%s", _("Error while writing to file"), \
-                _("File is incomplete."), \
-                gnome_vfs_result_to_string(vfs_result)); \
-        popup_error(_window, buffer); \
-        return FALSE; \
-    } \
-}
-
-static gboolean
-write_gpx(Path *path, GnomeVFSHandle *handle)
-{
-    Point *curr = NULL;
-    WayPoint *wcurr = NULL;
-    gboolean trkseg_break = FALSE;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    /* Find first non-zero point. */
-    for(curr = path->head - 1, wcurr = path->whead; curr++ != path->tail; )
-    {
-        if(curr->unity)
-            break;
-        else if(wcurr && curr == wcurr->point)
-            wcurr++;
-    }
-
-    /* Write the header. */
-    WRITE_STRING(
-            "<?xml version=\"1.0\"?>\n"
-            "<gpx version=\"1.0\" creator=\"maemo-mapper\" "
-            "xmlns=\"http://www.topografix.com/GPX/1/0\">\n"
-            "  <trk>\n"
-            "    <trkseg>\n");
-
-    /* Curr points to first non-zero point. */
-    for(curr--; curr++ != path->tail; )
-    {
-        gfloat lat, lon;
-        if(curr->unity)
-        {
-            gchar buffer[80];
-            gboolean first_sub = TRUE;
-            if(trkseg_break)
-            {
-                /* First trkpt of the segment - write trkseg header. */
-                WRITE_STRING("    </trkseg>\n"
-                             "    <trkseg>\n");
-                trkseg_break = FALSE;
-            }
-            unit2latlon(curr->unitx, curr->unity, lat, lon);
-            WRITE_STRING("      <trkpt lat=\"");
-            g_ascii_formatd(buffer, sizeof(buffer), "%.06f", lat);
-            WRITE_STRING(buffer);
-            WRITE_STRING("\" lon=\"");
-            g_ascii_formatd(buffer, sizeof(buffer), "%.06f", lon);
-            WRITE_STRING(buffer);
-            WRITE_STRING("\"");
-
-            /* write the elevation */
-            if(!isnan(curr->altitude))
-            {
-                if(first_sub)
-                {
-                    WRITE_STRING(">\n");
-                    first_sub = FALSE;
-                }
-                WRITE_STRING("        <ele>");
-                {
-                    g_ascii_formatd(buffer, 80, "%.2f", curr->altitude);
-                    WRITE_STRING(buffer);
-                }
-                WRITE_STRING("</ele>\n");
-            }
-
-            /* write the time */
-            if(curr->time)
-            {
-                if(first_sub)
-                {
-                    WRITE_STRING(">\n");
-                    first_sub = FALSE;
-                }
-                WRITE_STRING("        <time>");
-                strftime(buffer, 80, XML_DATE_FORMAT, localtime(&curr->time));
-                WRITE_STRING(buffer);
-                WRITE_STRING(XML_TZONE);
-                WRITE_STRING("</time>\n");
-            }
-
-            if(wcurr && curr == wcurr->point)
-            {
-                if(first_sub)
-                {
-                    WRITE_STRING(">\n");
-                    first_sub = FALSE;
-                }
-                WRITE_STRING("        <desc>");
-                WRITE_STRING(wcurr->desc);
-                WRITE_STRING("</desc>\n");
-                wcurr++;
-            }
-            if(first_sub)
-            {
-                WRITE_STRING("/>\n");
-            }
-            else
-            {
-                WRITE_STRING("      </trkpt>\n");
-            }
-        }
-        else
-            trkseg_break = TRUE;
-    }
-
-    /* Write the footer. */
-    WRITE_STRING(
-            "    </trkseg>\n"
-            "  </trk>\n"
-            "</gpx>\n");
-
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-speed_excess(void)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-    if(!_speed_excess)
-        return FALSE;
-
-    hildon_play_system_sound(
-        "/usr/share/sounds/ui-information_note.wav");
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static void
-speed_limit(void)
-{
-    GdkGC *gc;
-    gfloat cur_speed;
-    gchar *buffer;
-    static guint x = 0, y = 0, width = 0, height = 0;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    cur_speed = _gps.speed * UNITS_CONVERT[_units];
-
-    if(cur_speed > _speed_limit)
-    {
-        gc = _speed_limit_gc1;
-        if(!_speed_excess)
-        {
-            _speed_excess = TRUE;
-            g_timeout_add(5000, (GSourceFunc)speed_excess, NULL);
-        }
-    }
-    else
-    {
-        gc = _speed_limit_gc2;
-        _speed_excess = FALSE;
-    }
-
-    /* remove previous number */
-    if (width != 0 && height != 0) {
-      gtk_widget_queue_draw_area (_map_widget,
-                                 x - 5,
-                                 y - 5,
-                                 width + 10,
-                                 height + 10);
-      gdk_window_process_all_updates();
-    }
-
-    buffer = g_strdup_printf("%0.0f", cur_speed);
-    pango_layout_set_text(_speed_limit_layout, buffer, -1);
-
-
-    pango_layout_get_pixel_size(_speed_limit_layout, &width, &height);
-
-    switch (_speed_location)
-    {
-        case SPEED_LOCATION_TOP_RIGHT:
-            x = _map_widget->allocation.width - 10 - width;
-            y = 5;
-            break;
-        case SPEED_LOCATION_BOTTOM_RIGHT:
-            x = _map_widget->allocation.width - 10 - width;
-            y = _map_widget->allocation.height - 10 - height;
-            break;
-        case SPEED_LOCATION_BOTTOM_LEFT:
-            x = 10;
-            y = _map_widget->allocation.height - 10 - height;
-            break;
-        default:
-            x = 10;
-            y = 10;
-            break;
-    }
-
-    gdk_draw_layout(_map_widget->window,
-        gc,
-        x, y,
-        _speed_limit_layout);
-    g_free(buffer);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-/**
- * Handle a start tag in the parsing of a GPX file.
- */
-#define MACRO_SET_UNKNOWN() { \
-    data->prev_state = data->state; \
-    data->state = UNKNOWN; \
-    data->unknown_depth = 1; \
-}
-static void
-gpx_start_element(SaxData *data, const xmlChar *name, const xmlChar **attrs)
-{
-    vprintf("%s(%s)\n", __PRETTY_FUNCTION__, name);
-
-    switch(data->state)
-    {
-        case ERROR:
-            break;
-        case START:
-            if(!strcmp((gchar*)name, "gpx"))
-                data->state = INSIDE_GPX;
-            else
-                MACRO_SET_UNKNOWN();
-            break;
-        case INSIDE_GPX:
-            if(!strcmp((gchar*)name, "trk"))
-                data->state = INSIDE_PATH;
-            else
-                MACRO_SET_UNKNOWN();
-            break;
-        case INSIDE_PATH:
-            if(!strcmp((gchar*)name, "trkseg"))
-            {
-                data->state = INSIDE_PATH_SEGMENT;
-                data->at_least_one_trkpt = FALSE;
-            }
-            else
-                MACRO_SET_UNKNOWN();
-            break;
-        case INSIDE_PATH_SEGMENT:
-            if(!strcmp((gchar*)name, "trkpt"))
-            {
-                const xmlChar **curr_attr;
-                gchar *error_check;
-                gfloat lat = 0.f, lon = 0.f;
-                gboolean has_lat, has_lon;
-                has_lat = FALSE;
-                has_lon = FALSE;
-                for(curr_attr = attrs; *curr_attr != NULL; )
-                {
-                    const gchar *attr_name = *curr_attr++;
-                    const gchar *attr_val = *curr_attr++;
-                    if(!strcmp(attr_name, "lat"))
-                    {
-                        lat = g_ascii_strtod(attr_val, &error_check);
-                        if(error_check != attr_val)
-                            has_lat = TRUE;
-                    }
-                    else if(!strcmp(attr_name, "lon"))
-                    {
-                        lon = g_ascii_strtod(attr_val, &error_check);
-                        if(error_check != attr_val)
-                            has_lon = TRUE;
-                    }
-                }
-                if(has_lat && has_lon)
-                {
-                    MACRO_PATH_INCREMENT_TAIL(data->path);
-                    latlon2unit(lat, lon,
-                            data->path.tail->unitx,
-                            data->path.tail->unity);
-                    data->path.tail->time = 0;
-                    data->path.tail->altitude = NAN;
-                    data->state = INSIDE_PATH_POINT;
-                }
-                else
-                    data->state = ERROR;
-            }
-            else
-                MACRO_SET_UNKNOWN();
-            break;
-        case INSIDE_PATH_POINT:
-            if(!strcmp((gchar*)name, "time"))
-                data->state = INSIDE_PATH_POINT_TIME;
-            else if(!strcmp((gchar*)name, "ele"))
-                data->state = INSIDE_PATH_POINT_ELE;
-            else if(!strcmp((gchar*)name, "desc"))
-                data->state = INSIDE_PATH_POINT_DESC;
-
-            else
-                MACRO_SET_UNKNOWN();
-            break;
-        case UNKNOWN:
-            data->unknown_depth++;
-            break;
-        default:
-            ;
-    }
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-/**
- * Handle an end tag in the parsing of a GPX file.
- */
-static void
-gpx_end_element(SaxData *data, const xmlChar *name)
-{
-    vprintf("%s(%s)\n", __PRETTY_FUNCTION__, name);
-
-    switch(data->state)
-    {
-        case ERROR:
-            break;
-        case START:
-            data->state = ERROR;
-            break;
-        case INSIDE_GPX:
-            if(!strcmp((gchar*)name, "gpx"))
-                data->state = FINISH;
-            else
-                data->state = ERROR;
-            break;
-        case INSIDE_PATH:
-            if(!strcmp((gchar*)name, "trk"))
-                data->state = INSIDE_GPX;
-            else
-                data->state = ERROR;
-            break;
-        case INSIDE_PATH_SEGMENT:
-            if(!strcmp((gchar*)name, "trkseg"))
-            {
-                if(data->at_least_one_trkpt)
-                {
-                    MACRO_PATH_INCREMENT_TAIL(data->path);
-                    *data->path.tail = _point_null;
-                }
-                data->state = INSIDE_PATH;
-            }
-            else
-                data->state = ERROR;
-            break;
-        case INSIDE_PATH_POINT:
-            if(!strcmp((gchar*)name, "trkpt"))
-            {
-                data->state = INSIDE_PATH_SEGMENT;
-                data->at_least_one_trkpt = TRUE;
-            }
-            else
-                data->state = ERROR;
-            break;
-        case INSIDE_PATH_POINT_ELE:
-            if(!strcmp((gchar*)name, "ele"))
-            {
-                gchar *error_check;
-                data->path.tail->altitude
-                    = g_ascii_strtod(data->chars->str, &error_check);
-                if(error_check == data->chars->str)
-                    data->path.tail->altitude = NAN;
-                data->state = INSIDE_PATH_POINT;
-                g_string_free(data->chars, TRUE);
-                data->chars = g_string_new("");
-            }
-            else
-                data->state = ERROR;
-            break;
-        case INSIDE_PATH_POINT_TIME:
-            if(!strcmp((gchar*)name, "time"))
-            {
-                struct tm time;
-                gchar *ptr;
-
-                if(NULL == (ptr = strptime(data->chars->str,
-                            XML_DATE_FORMAT, &time)))
-                    /* Failed to parse dateTime format. */
-                    data->state = ERROR;
-                else
-                {
-                    /* Parse was successful. Now we have to parse timezone.
-                     * From here on, if there is an error, I just assume local
-                     * timezone.  Yes, this is not proper XML, but I don't
-                     * care. */
-                    gchar *error_check;
-
-                    /* First, set time in "local" time zone. */
-                    data->path.tail->time = (mktime(&time));
-
-                    /* Now, skip inconsequential characters */
-                    while(*ptr && *ptr != 'Z' && *ptr != '-' && *ptr != '+')
-                        ptr++;
-
-                    /* Check if we ran to the end of the string. */
-                    if(*ptr)
-                    {
-                        /* Next character is either 'Z', '-', or '+' */
-                        if(*ptr == 'Z')
-                            /* Zulu (UTC) time. Undo the local time zone's
-                             * offset. */
-                            data->path.tail->time += time.tm_gmtoff;
-                        else
-                        {
-                            /* Not Zulu (UTC). Must parse hours and minutes. */
-                            gint offhours = strtol(ptr, &error_check, 10);
-                            if(error_check != ptr
-                                    && *(ptr = error_check) == ':')
-                            {
-                                /* Parse of hours worked. Check minutes. */
-                                gint offmins = strtol(ptr + 1,
-                                        &error_check, 10);
-                                if(error_check != (ptr + 1))
-                                {
-                                    /* Parse of minutes worked. Calculate. */
-                                    data->path.tail->time
-                                        += (time.tm_gmtoff
-                                                - (offhours * 60 * 60
-                                                    + offmins * 60));
-                                }
-                            }
-                        }
-                    }
-                    /* Successfully parsed dateTime. */
-                    data->state = INSIDE_PATH_POINT;
-                }
-
-                g_string_free(data->chars, TRUE);
-                data->chars = g_string_new("");
-            }
-            else
-                data->state = ERROR;
-            break;
-        case INSIDE_PATH_POINT_DESC:
-            /* only parse description for routes */
-            if(!strcmp((gchar*)name, "desc"))
-            {
-                MACRO_PATH_INCREMENT_WTAIL(data->path);
-                data->path.wtail->point= data->path.tail;
-                data->path.wtail->desc
-                    = g_string_free(data->chars, FALSE);
-                data->chars = g_string_new("");
-                data->state = INSIDE_PATH_POINT;
-            }
-            else
-                data->state = ERROR;
-            break;
-        case UNKNOWN:
-            if(!--data->unknown_depth)
-                data->state = data->prev_state;
-            else
-                data->state = ERROR;
-            break;
-        default:
-            ;
-    }
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-/**
- * Handle char data in the parsing of a GPX file.
- */
-static void
-gpx_chars(SaxData *data, const xmlChar *ch, int len)
-{
-    guint i;
-    vprintf("%s()\n", __PRETTY_FUNCTION__);
-
-    switch(data->state)
-    {
-        case ERROR:
-        case UNKNOWN:
-            break;
-        case INSIDE_PATH_POINT_ELE:
-        case INSIDE_PATH_POINT_TIME:
-        case INSIDE_PATH_POINT_DESC:
-            for(i = 0; i < len; i++)
-                data->chars = g_string_append_c(data->chars, ch[i]);
-            vprintf("%s\n", data->chars->str);
-            break;
-        default:
-            break;
-    }
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-/**
- * Handle an entity in the parsing of a GPX file.  We don't do anything
- * special here.
- */
-static xmlEntityPtr
-gpx_get_entity(SaxData *data, const xmlChar *name)
-{
-    vprintf("%s()\n", __PRETTY_FUNCTION__);
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-    return xmlGetPredefinedEntity(name);
-}
-
-/**
- * Handle an error in the parsing of a GPX file.
- */
-static void
-gpx_error(SaxData *data, const gchar *msg, ...)
-{
-    vprintf("%s()\n", __PRETTY_FUNCTION__);
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-    data->state = ERROR;
-}
-
-static gboolean
-parse_gpx(Path *to_replace, gchar *buffer, gint size, gint policy_old)
-{
-    SaxData data;
-    xmlSAXHandler sax_handler;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    MACRO_PATH_INIT(data.path);
-    data.state = START;
-    data.chars = g_string_new("");
-
-    memset(&sax_handler, 0, sizeof(sax_handler));
-    sax_handler.characters = (charactersSAXFunc)gpx_chars;
-    sax_handler.startElement = (startElementSAXFunc)gpx_start_element;
-    sax_handler.endElement = (endElementSAXFunc)gpx_end_element;
-    sax_handler.entityDecl = (entityDeclSAXFunc)gpx_get_entity;
-    sax_handler.warning = (warningSAXFunc)gpx_error;
-    sax_handler.error = (errorSAXFunc)gpx_error;
-    sax_handler.fatalError = (fatalErrorSAXFunc)gpx_error;
-
-    xmlSAXUserParseMemory(&sax_handler, &data, buffer, size);
-    g_string_free(data.chars, TRUE);
-
-    if(data.state != FINISH)
-    {
-        vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
-        return FALSE;
-    }
-
-    if(policy_old && to_replace->head != to_replace->tail)
-    {
-        Point *src_first;
-        Path *src, *dest;
-
-        if(policy_old > 0)
-        {
-            /* Append to current path. Make sure last path point is zero. */
-            if(to_replace->tail->unity != 0)
-            {
-                MACRO_PATH_INCREMENT_TAIL((*to_replace));
-                *to_replace->tail = _point_null;
-            }
-            src = &data.path;
-            dest = to_replace;
-        }
-        else
-        {
-            /* Prepend to current route. */
-            src = to_replace;
-            dest = &data.path;
-        }
-
-        /* Find src_first non-zero point. */
-        for(src_first = src->head - 1; src_first++ != src->tail; )
-            if(src_first->unity)
-                break;
-
-        /* Append route points from src to dest. */
-        if(src->tail >= src_first)
-        {
-            WayPoint *curr;
-            guint num_dest_points = dest->tail - dest->head + 1;
-            guint num_src_points = src->tail - src_first + 1;
-
-            /* Adjust dest->tail to be able to fit src route data
-             * plus room for more route data. */
-            path_resize(dest, num_dest_points + num_src_points);
-
-            memcpy(dest->tail + 1, src_first,
-                    num_src_points * sizeof(Point));
-
-            dest->tail += num_src_points;
-
-            /* Append waypoints from src to dest->. */
-            path_wresize(dest, (dest->wtail - dest->whead)
-                    + (src->wtail - src->whead) + 2);
-            for(curr = src->whead - 1; curr++ != src->wtail; )
-            {
-                (++(dest->wtail))->point = dest->head + num_dest_points
-                    + (curr->point - src_first);
-                dest->wtail->desc = curr->desc;
-            }
-
-        }
-
-        /* Kill old route - don't use MACRO_PATH_FREE(), because that
-         * would free the string desc's that we just moved to data.route. */
-        g_free(src->head);
-        g_free(src->whead);
-        if(policy_old < 0)
-            (*to_replace) = *dest;
-    }
-    else
-    {
-        MACRO_PATH_FREE((*to_replace));
-        /* Overwrite with data.route. */
-        (*to_replace) = data.path;
-        path_resize(to_replace, to_replace->tail - to_replace->head + 1);
-        path_wresize(to_replace, to_replace->wtail - to_replace->whead + 1);
-    }
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-/****************************************************************************
- * ABOVE: FILE-HANDLING ROUTINES *********************************************
- ****************************************************************************/
-
-
-/****************************************************************************
- * BELOW: ROUTINES **********************************************************
- ****************************************************************************/
-
-static void
-deg_format(gfloat coor, gchar *scoor, gchar neg_char, gchar pos_char)
-{
-    gfloat min;
-    gfloat acoor = fabs(coor);
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    switch(_degformat)
-    {
-        case DDPDDDDD:
-            sprintf(scoor, "%.5f°", coor);
-            break;
-        case DDPDDDDD_NSEW:
-            sprintf(scoor, "%.5f° %c", acoor,
-                    coor < 0.f ? neg_char : pos_char);
-            break;
-        case NSEW_DDPDDDDD:
-            sprintf(scoor, "%c %.5f°",
-                    coor < 0.f ? neg_char : pos_char,
-                    acoor);
-            break;
-
-        case DD_MMPMMM:
-            sprintf(scoor, "%d°%06.3f'",
-                    (int)coor, (acoor - (int)acoor)*60.0);
-            break;
-        case DD_MMPMMM_NSEW:
-            sprintf(scoor, "%d°%06.3f' %c",
-                    (int)acoor, (acoor - (int)acoor)*60.0,
-                    coor < 0.f ? neg_char : pos_char);
-            break;
-        case NSEW_DD_MMPMMM:
-            sprintf(scoor, "%c %d° %06.3f'",
-                    coor < 0.f ? neg_char : pos_char,
-                    (int)acoor, (acoor - (int)acoor)*60.0);
-            break;
-
-        case DD_MM_SSPS:
-            min = (acoor - (int)acoor)*60.0;
-            sprintf(scoor, "%d°%02d'%04.1f\"", (int)coor, (int)min,
-                    ((min - (int)min)*60.0));
-            break;
-        case DD_MM_SSPS_NSEW:
-            min = (acoor - (int)acoor)*60.0;
-            sprintf(scoor, "%d°%02d'%04.1f\" %c", (int)acoor, (int)min,
-                    ((min - (int)min)*60.0),
-                    coor < 0.f ? neg_char : pos_char);
-            break;
-        case NSEW_DD_MM_SSPS:
-            min = (acoor - (int)acoor)*60.0;
-            sprintf(scoor, "%c %d° %02d' %04.1f\"",
-                    coor < 0.f ? neg_char : pos_char,
-                    (int)acoor, (int)min,
-                    ((min - (int)min)*60.0));
-            break;
-    }
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static gboolean
-gps_display_details(void)
-{
-    gchar *buffer, litbuf[16];
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(_gps.fix < 2)
-    {
-        /* no fix no fun */
-        gtk_label_set_label(GTK_LABEL(_sdi_lat), " --- ");
-        gtk_label_set_label(GTK_LABEL(_sdi_lon), " --- ");
-        gtk_label_set_label(GTK_LABEL(_sdi_spd), " --- ");
-        gtk_label_set_label(GTK_LABEL(_sdi_alt), " --- ");
-        gtk_label_set_label(GTK_LABEL(_sdi_hea), " --- ");
-        gtk_label_set_label(GTK_LABEL(_sdi_tim), " --:--:-- ");
-    }
-    else
-    {
-        gfloat speed = _gps.speed * UNITS_CONVERT[_units];
-
-        /* latitude */
-        lat_format(_gps.lat, litbuf);
-        gtk_label_set_label(GTK_LABEL(_sdi_lat), litbuf);
-
-        /* longitude */
-        lon_format(_gps.lon, litbuf);
-        gtk_label_set_label(GTK_LABEL(_sdi_lon), litbuf);
-
-        /* speed */
-        switch(_units)
-        {
-            case UNITS_MI:
-                buffer = g_strdup_printf("%.1f mph", speed);
-                break;
-            case UNITS_NM:
-                buffer = g_strdup_printf("%.1f kn", speed);
-                break;
-            default:
-                buffer = g_strdup_printf("%.1f km/h", speed);
-                break;
-        }
-        gtk_label_set_label(GTK_LABEL(_sdi_spd), buffer);
-        g_free(buffer);
-
-        /* altitude */
-        switch(_units)
-        {
-            case UNITS_MI:
-            case UNITS_NM:
-                buffer = g_strdup_printf("%.1f ft",
-                        _pos.altitude * 3.2808399f);
-                break;
-            default:
-                buffer = g_strdup_printf("%.1f m", _pos.altitude);
-                break;
-        }
-        gtk_label_set_label(GTK_LABEL(_sdi_alt), buffer);
-        g_free(buffer);
-
-        /* heading */
-        buffer = g_strdup_printf("%0.0f°", _gps.heading);
-        gtk_label_set_label(GTK_LABEL(_sdi_hea), buffer);
-        g_free(buffer);
-
-        /* local time */
-        strftime(litbuf, 15, "%X", localtime(&_pos.time));
-        gtk_label_set_label(GTK_LABEL(_sdi_tim), litbuf);
-    }
-
-    /* Sat in view */
-    buffer = g_strdup_printf("%d", _gps.satinview);
-    gtk_label_set_label(GTK_LABEL(_sdi_vie), buffer);
-    g_free(buffer);
-
-    /* Sat in use */
-    buffer = g_strdup_printf("%d", _gps.satinuse);
-    gtk_label_set_label(GTK_LABEL(_sdi_use), buffer);
-    g_free(buffer);
-
-    /* fix */
-    switch(_gps.fix)
-    {
-        case 2:
-        case 3: buffer = g_strdup_printf("%dD fix", _gps.fix); break;
-        default: buffer = g_strdup_printf("nofix"); break;
-    }
-    gtk_label_set_label(GTK_LABEL(_sdi_fix), buffer);
-    g_free(buffer);
-
-    if(_gps.fix == 1)
-        buffer = g_strdup("none");
-    else
-    {
-        switch (_gps.fixquality)
-        {
-            case 1 : buffer = g_strdup_printf(_("SPS")); break;
-            case 2 : buffer = g_strdup_printf(_("DGPS")); break;
-            case 3 : buffer = g_strdup_printf(_("PPS")); break;
-            case 4 : buffer = g_strdup_printf(_("Real Time Kinematic")); break;
-            case 5 : buffer = g_strdup_printf(_("Float RTK")); break;
-            case 6 : buffer = g_strdup_printf(_("Estimated")); break;
-            case 7 : buffer = g_strdup_printf(_("Manual")); break;
-            case 8 : buffer = g_strdup_printf(_("Simulation")); break;
-            default : buffer = g_strdup_printf(_("none")); break;
-        }
-    }
-    gtk_label_set_label(GTK_LABEL(_sdi_fqu), buffer);
-    g_free(buffer);
-
-    /* max speed */
-    {
-        gfloat maxspeed = _gps.maxspeed * UNITS_CONVERT[_units];
-
-        /* speed */
-        switch(_units)
-        {
-            case UNITS_MI:
-                buffer = g_strdup_printf("%.1f mph", maxspeed);
-                break;
-            case UNITS_NM:
-                buffer = g_strdup_printf("%.1f kn", maxspeed);
-                break;
-            default:
-                buffer = g_strdup_printf("%.1f km/h", maxspeed);
-                break;
-        }
-        gtk_label_set_label(GTK_LABEL(_sdi_msp), buffer);
-        g_free(buffer);
-    }
-
-    /* refresh sat panel */
-    gtk_widget_queue_draw_area(GTK_WIDGET(_sat_details_panel),
-        0, 0,
-        _sat_details_panel->allocation.width,
-        _sat_details_panel->allocation.height);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static void
-gps_display_data(void)
-{
-    gchar *buffer, litbuf[LL_FMT_LEN];
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(_gps.fix < 2)
-    {
-        /* no fix no fun */
-        gtk_label_set_label(GTK_LABEL(_text_lat), " --- ");
-        gtk_label_set_label(GTK_LABEL(_text_lon), " --- ");
-        gtk_label_set_label(GTK_LABEL(_text_speed), " --- ");
-        gtk_label_set_label(GTK_LABEL(_text_alt), " --- ");
-        gtk_label_set_label(GTK_LABEL(_text_time), " --:--:-- ");
-    }
-    else
-    {
-        gfloat speed = _gps.speed * UNITS_CONVERT[_units];
-
-        /* latitude */
-        lat_format(_gps.lat, litbuf);
-        gtk_label_set_label(GTK_LABEL(_text_lat), litbuf);
-
-        /* longitude */
-        lon_format(_gps.lon, litbuf);
-        gtk_label_set_label(GTK_LABEL(_text_lon), litbuf);
-
-        /* speed */
-        switch(_units)
-        {
-            case UNITS_MI:
-                buffer = g_strdup_printf("Spd: %.1f mph", speed);
-                break;
-            case UNITS_NM:
-                buffer = g_strdup_printf("Spd: %.1f kn", speed);
-                break;
-            default:
-                buffer = g_strdup_printf("Spd: %.1f km/h", speed);
-                break;
-        }
-        gtk_label_set_label(GTK_LABEL(_text_speed), buffer);
-        g_free(buffer);
-
-        /* altitude */
-        switch(_units)
-        {
-            case UNITS_MI:
-            case UNITS_NM:
-                buffer = g_strdup_printf("Alt: %.1f ft",
-                        _pos.altitude * 3.2808399f);
-                break;
-            default:
-                buffer = g_strdup_printf("Alt: %.1f m", _pos.altitude);
-        }
-        gtk_label_set_label(GTK_LABEL(_text_alt), buffer);
-        g_free(buffer);
-
-        /* local time */
-        strftime(litbuf, 15, "%X", localtime(&_pos.time));
-        gtk_label_set_label(GTK_LABEL(_text_time), litbuf);
-    }
-
-    /* refresh sat panel */
-    gtk_widget_queue_draw_area(GTK_WIDGET(_sat_panel),
-        0, 0,
-        _sat_panel->allocation.width,
-        _sat_panel->allocation.height);
-
-    /* refresh heading panel*/
-    gtk_widget_queue_draw_area(GTK_WIDGET(_heading_panel),
-        0, 0,
-        _heading_panel->allocation.width,
-        _heading_panel->allocation.height);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-    return;
-}
-
-static void
-gps_hide_text(void)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    /* Clear gps data */
-    _gps.fix = 1;
-    _gps.satinuse = 0;
-    _gps.satinview = 0;
-
-    if(_gps_info)
-        gps_display_data();
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static void
-gps_show_info(void)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(_gps_info && _enable_gps)
-        gtk_widget_show_all(GTK_WIDGET(_gps_widget));
-    else
-    {
-        gps_hide_text();
-        gtk_widget_hide_all(GTK_WIDGET(_gps_widget));
-    }
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static void
-draw_sat_info(GtkWidget *widget, guint x0, guint y0,
-        guint width, guint height, gboolean showsnr)
-{
-    GdkGC *gc;
-    guint step, i, j, snr_height, bymargin, xoffset, yoffset;
-    guint x, y, x1, y1;
-    gchar *tmp = NULL;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    xoffset = x0;
-    yoffset = y0;
-    /* Bootom margin - 12% */
-    bymargin = height * 0.88f;
-
-    /* Bottom line */
-    gdk_draw_line(widget->window,
-        widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
-        xoffset + 5, yoffset + bymargin,
-        xoffset + width - 10 - 2, yoffset + bymargin);
-    gdk_draw_line(widget->window,
-        widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
-        xoffset + 5, yoffset + bymargin - 1,
-        xoffset + width - 10 - 2, yoffset + bymargin - 1);
-
-    if(_gps.satinview > 0 )
-    {
-        /* Left margin - 5pix, Right margin - 5pix */
-        step = (width - 10) / _gps.satinview;
-
-        for(i = 0; i < _gps.satinview; i++)
-        {
-            /* Sat used or not */
-            gc = _sat_info_gc1;
-            for(j = 0; j < _gps.satinuse ; j++)
-            {
-                if(_gps.satforfix[j] == _gps_sat[i].prn)
-                {
-                    gc = _sat_info_gc2;
-                    break;
-                }
-            }
-
-            x = 5 + i * step;
-            snr_height = _gps_sat[i].snr * height * 0.78f / 100;
-            y = height * 0.1f + (height * 0.78f - snr_height);
-
-            /* draw sat rectangle... */
-            gdk_draw_rectangle(widget->window,
-                    gc,
-                    TRUE,
-                    xoffset + x,
-                    yoffset + y,
-                    step - 2,
-                    snr_height);
-
-            if(showsnr && _gps_sat[i].snr > 0)
-            {
-                /* ...snr.. */
-                tmp = g_strdup_printf("%02d", _gps_sat[i].snr);
-                pango_layout_set_text(_sat_info_layout, tmp, 2);
-                pango_layout_get_pixel_size(_sat_info_layout, &x1, &y1);
-                gdk_draw_layout(widget->window,
-                    widget->style->fg_gc[GTK_STATE_NORMAL],
-                    xoffset + x + ((step - 2) - x1)/2,
-                    yoffset + y - 15,
-                    _sat_info_layout);
-                g_free(tmp);
-            }
-
-            /* ...and sat number */
-            tmp = g_strdup_printf("%02d", _gps_sat[i].prn);
-            pango_layout_set_text(_sat_info_layout, tmp, 2);
-            pango_layout_get_pixel_size(_sat_info_layout, &x1, &y1);
-            gdk_draw_layout(widget->window,
-                widget->style->fg_gc[GTK_STATE_NORMAL],
-                xoffset + x + ((step - 2) - x1)/2 ,
-                yoffset + bymargin + 1,
-                _sat_info_layout);
-            g_free(tmp);
-        }
-    }
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-    return;
-}
-
-static void
-draw_sat_details(GtkWidget *widget, guint x0, guint y0,
-        guint width, guint height)
-{
-    guint i, j, x, y, size, halfsize, xoffset, yoffset;
-    guint x1, y1;
-    gfloat tmp;
-    GdkColor color;
-    GdkGC *gc1, *gc2, *gc3, *gc;
-    gchar *buffer = NULL;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    size = MIN(width, height);
-    halfsize = size/2;
-    if(width > height)
-    {
-        xoffset = x0 + (width - height - 10) / 2;
-        yoffset = y0 + 5;
-    }
-    else
-    {
-        xoffset = x0 + 5;
-        yoffset = y0 + (height - width - 10) / 2;
-    }
-
-    /* 90 */
-    gdk_draw_arc(widget->window,
-            widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
-            FALSE,
-            xoffset + 2, yoffset + 2, size - 4, size - 4,
-            0, 64 * 360);
-
-    /* 60 */
-    gdk_draw_arc(widget->window,
-            widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
-            FALSE,
-            xoffset + size/6, yoffset + size/6,
-            size/6*4, size/6*4,
-            0, 64 * 360);
-
-    /* 30 */
-    gdk_draw_arc(widget->window,
-            widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
-            FALSE,
-            xoffset + size/6*2, yoffset + size/6*2,
-            size/6*2, size/6*2,
-            0, 64 * 360);
-
-    guint line[12] = {0,30,60,90,120,150,180,210,240,270,300,330};
-
-    for(i = 0; i < 6; i++)
-    {
-        /* line */
-        tmp = (line[i] * (1.f / 180.f)) * PI;
-        gdk_draw_line(widget->window,
-            widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
-            xoffset + halfsize + (halfsize -2) * sinf(tmp),
-            yoffset + halfsize - (halfsize -2) * cosf(tmp),
-            xoffset + halfsize - (halfsize -2) * sinf(tmp),
-            yoffset + halfsize + (halfsize -2) * cosf(tmp));
-    }
-
-    for(i = 0; i < 12; i++)
-    {
-        tmp = (line[i] * (1.f / 180.f)) * PI;
-        /* azimuth */
-        if(line[i] == 0)
-            buffer = g_strdup_printf("N");
-        else
-            buffer = g_strdup_printf("%d°", line[i]);
-        pango_layout_set_text(_sat_details_layout, buffer, -1);
-        pango_layout_get_pixel_size(_sat_details_layout, &x, &y);
-        gdk_draw_layout(widget->window,
-            widget->style->fg_gc[GTK_STATE_NORMAL],
-            (xoffset + halfsize + (halfsize - size/12) * sinf(tmp)) - x/2,
-            (yoffset + halfsize - (halfsize - size/12) * cosf(tmp)) - y/2,
-            _sat_details_layout);
-        g_free(buffer);
-    }
-
-    /* elevation 30 */
-    tmp = (30 * (1.f / 180.f)) * PI;
-    buffer = g_strdup_printf("30°");
-    pango_layout_set_text(_sat_details_layout, buffer, -1);
-    pango_layout_get_pixel_size(_sat_details_layout, &x, &y);
-    gdk_draw_layout(widget->window,
-        widget->style->fg_gc[GTK_STATE_NORMAL],
-        (xoffset + halfsize + size/6*2 * sinf(tmp)) - x/2,
-        (yoffset + halfsize - size/6*2 * cosf(tmp)) - y/2,
-        _sat_details_layout);
-    g_free(buffer);
-
-    /* elevation 60 */
-    tmp = (30 * (1.f / 180.f)) * PI;
-    buffer = g_strdup_printf("60°");
-    pango_layout_set_text(_sat_details_layout, buffer, -1);
-    pango_layout_get_pixel_size(_sat_details_layout, &x, &y);
-    gdk_draw_layout(widget->window,
-        widget->style->fg_gc[GTK_STATE_NORMAL],
-        (xoffset + halfsize + size/6 * sinf(tmp)) - x/2,
-        (yoffset + halfsize - size/6 * cosf(tmp)) - y/2,
-        _sat_details_layout);
-    g_free(buffer);
-
-    color.red = 0;
-    color.green = 0;
-    color.blue = 0;
-    gc1 = gdk_gc_new (widget->window);
-    gdk_gc_set_rgb_fg_color (gc1, &color);
-
-    color.red = 0;
-    color.green = 0;
-    color.blue = 0xffff;
-    gc2 = gdk_gc_new (widget->window);
-    gdk_gc_set_rgb_fg_color (gc2, &color);
-
-    color.red = 0xffff;
-    color.green = 0xffff;
-    color.blue = 0xffff;
-    gc3 = gdk_gc_new (widget->window);
-    gdk_gc_set_rgb_fg_color (gc3, &color);
-
-    for(i = 0; i < _gps.satinview; i++)
-    {
-        /* Sat used or not */
-        gc = gc1;
-        for(j = 0; j < _gps.satinuse ; j++)
-        {
-            if(_gps.satforfix[j] == _gps_sat[i].prn)
-            {
-                gc = gc2;
-                break;
-            }
-        }
-
-        tmp = (_gps_sat[i].azimuth * (1.f / 180.f)) * PI;
-        x = xoffset + halfsize
-            + (90 - _gps_sat[i].elevation)*halfsize/90 * sinf(tmp);
-        y = yoffset + halfsize
-            - (90 - _gps_sat[i].elevation)*halfsize/90 * cosf(tmp);
-
-        gdk_draw_arc (widget->window,
-            gc, TRUE,
-            x - 10, y - 10, 20, 20,
-            0, 64 * 360);
-
-        buffer = g_strdup_printf("%02d", _gps_sat[i].prn);
-        pango_layout_set_text(_sat_details_layout, buffer, -1);
-        pango_layout_get_pixel_size(_sat_details_layout, &x1, &y1);
-        gdk_draw_layout(widget->window,
-            gc3,
-            x - x1/2,
-            y - y1/2,
-            _sat_details_layout);
-        g_free(buffer);
-    }
-    g_object_unref (gc1);
-    g_object_unref (gc2);
-    g_object_unref (gc3);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-    return;
-}
-
-
-static gboolean
-sat_details_panel_expose(GtkWidget *widget, GdkEventExpose *event)
-{
-    guint width, height, x, y;
-    gchar *buffer = NULL;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    width = widget->allocation.width;
-    height = widget->allocation.height * 0.9;
-
-    draw_sat_info(widget, 0, 0, width/2, height, TRUE);
-    draw_sat_details(widget, width/2, 0, width/2, height);
-
-    buffer = g_strdup_printf(
-        "%s: %d; %s: %d",
-        _("Satellites in view"), _gps.satinview,
-        _("in use"), _gps.satinuse);
-    pango_layout_set_text(_sat_details_expose_layout, buffer, -1);
-    pango_layout_get_pixel_size(_sat_details_expose_layout, &x, &y);
-    gdk_draw_layout(widget->window,
-        widget->style->fg_gc[GTK_STATE_NORMAL],
-        10,
-        height*0.9 + 10,
-        _sat_details_expose_layout);
-    g_free(buffer);
-
-    buffer = g_strdup_printf("HDOP: %.01f", _gps.hdop);
-    pango_layout_set_text(_sat_details_expose_layout, buffer, -1);
-    pango_layout_get_pixel_size(_sat_details_expose_layout, &x, &y);
-    gdk_draw_layout(widget->window,
-        widget->style->fg_gc[GTK_STATE_NORMAL],
-        (width/8) - x/2,
-        (height/6) - y/2,
-        _sat_details_expose_layout);
-    g_free(buffer);
-    buffer = g_strdup_printf("PDOP: %.01f", _gps.pdop);
-    pango_layout_set_text(_sat_details_expose_layout, buffer, -1);
-    pango_layout_get_pixel_size(_sat_details_expose_layout, &x, &y);
-    gdk_draw_layout(widget->window,
-        widget->style->fg_gc[GTK_STATE_NORMAL],
-        (width/8) - x/2,
-        (height/6) - y/2 + 20,
-        _sat_details_expose_layout);
-    g_free(buffer);
-    buffer = g_strdup_printf("VDOP: %.01f", _gps.vdop);
-    pango_layout_set_text(_sat_details_expose_layout, buffer, -1);
-    pango_layout_get_pixel_size(_sat_details_expose_layout, &x, &y);
-    gdk_draw_layout(widget->window,
-        widget->style->fg_gc[GTK_STATE_NORMAL],
-        (width/8) - x/2,
-        (height/6) - y/2 + 40,
-        _sat_details_expose_layout);
-    g_free(buffer);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static void
-gps_details(void)
-{
-    static GtkWidget *dialog = NULL;
-    static GtkWidget *table = NULL;
-    static GtkWidget *label = NULL;
-    static GtkWidget *notebook = NULL;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(dialog == NULL)
-    {
-        dialog = gtk_dialog_new_with_buttons(_("GPS Details"),
-                GTK_WINDOW(_window), GTK_DIALOG_MODAL,
-                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
-                NULL);
-
-        gtk_window_set_default_size(GTK_WINDOW(dialog), 600, 300);
-
-        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
-                notebook = gtk_notebook_new(), TRUE, TRUE, 0);
-
-        /* textual info */
-        gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
-                table = gtk_table_new(4, 6, FALSE),
-                label = gtk_label_new(_("GPS Information")));
-
-        _sat_details_panel = gtk_drawing_area_new ();
-        gtk_widget_set_size_request (_sat_details_panel, 300, 300);
-        /* sat details info */
-        gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
-                _sat_details_panel,
-                label = gtk_label_new(_("Satellites details")));
-        g_signal_connect (G_OBJECT (_sat_details_panel), "expose_event",
-                            G_CALLBACK (sat_details_panel_expose), NULL);
-
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("Latitude")),
-                0, 1, 0, 1, GTK_EXPAND | GTK_FILL, 0, 20, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(table),
-                _sdi_lat = gtk_label_new(" --- "),
-                1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(_sdi_lat), 0.f, 0.5f);
-
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("Longitude")),
-                0, 1, 1, 2, GTK_EXPAND | GTK_FILL, 0, 20, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(table),
-                _sdi_lon = gtk_label_new(" --- "),
-                1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(_sdi_lon), 0.f, 0.5f);
-
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("Speed")),
-                0, 1, 2, 3, GTK_EXPAND | GTK_FILL, 0, 20, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(table),
-                _sdi_spd = gtk_label_new(" --- "),
-                1, 2, 2, 3, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(_sdi_spd), 0.f, 0.5f);
-
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("Altitude")),
-                0, 1, 3, 4, GTK_EXPAND | GTK_FILL, 0, 20, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(table),
-                _sdi_alt = gtk_label_new(" --- "),
-                1, 2, 3, 4, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(_sdi_alt), 0.f, 0.5f);
-
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("Heading")),
-                0, 1, 4, 5, GTK_EXPAND | GTK_FILL, 0, 20, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(table),
-                _sdi_hea = gtk_label_new(" --- "),
-                1, 2, 4, 5, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(_sdi_hea), 0.f, 0.5f);
-
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("Local time")),
-                0, 1, 5, 6, GTK_EXPAND | GTK_FILL, 0, 20, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(table),
-                _sdi_tim = gtk_label_new(" --:--:-- "),
-                1, 2, 5, 6, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(_sdi_tim), 0.f, 0.5f);
-
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("Sat in view")),
-                2, 3, 0, 1, GTK_EXPAND | GTK_FILL, 0, 20, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(table),
-                _sdi_vie = gtk_label_new("0"),
-                3, 4, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(_sdi_vie), 0.f, 0.5f);
-
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("Sat in use")),
-                2, 3, 1, 2, GTK_EXPAND | GTK_FILL, 0, 20, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(table),
-                _sdi_use = gtk_label_new("0"),
-                3, 4, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(_sdi_use), 0.f, 0.5f);
-
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("Fix")),
-                2, 3, 2, 3, GTK_EXPAND | GTK_FILL, 0, 20, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(table),
-                _sdi_fix = gtk_label_new(_("nofix")),
-                3, 4, 2, 3, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(_sdi_fix), 0.f, 0.5f);
-
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("Fix Quality")),
-                2, 3, 3, 4, GTK_EXPAND | GTK_FILL, 0, 20, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(table),
-                _sdi_fqu = gtk_label_new(_("none")),
-                3, 4, 3, 4, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(_sdi_fqu), 0.f, 0.5f);
-
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("Max speed")),
-                2, 3, 5, 6, GTK_EXPAND | GTK_FILL, 0, 20, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(table),
-                _sdi_msp = gtk_label_new(" --- "),
-                3, 4, 5, 6, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(_sdi_msp), 0.f, 0.5f);
-    }
-
-    gtk_widget_show_all(dialog);
-    _satdetails_on = TRUE;
-    gps_display_details();
-    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
-    {
-        _satdetails_on = FALSE;
-        break;
-    }
-    gtk_widget_hide(dialog);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-/**
- * Calculate the distance between two lat/lon pairs.  The distance is returned
- * in kilometers and should be converted using UNITS_CONVERT[_units].
- */
-static gfloat
-calculate_distance(gfloat lat1, gfloat lon1, gfloat lat2, gfloat lon2)
-{
-    gfloat dlat, dlon, slat, slon, a;
-
-    /* Convert to radians. */
-    lat1 *= (PI / 180.f);
-    lon1 *= (PI / 180.f);
-    lat2 *= (PI / 180.f);
-    lon2 *= (PI / 180.f);
-
-    dlat = lat2 - lat1;
-    dlon = lon2 - lon1;
-
-    slat = sinf(dlat / 2.f);
-    slon = sinf(dlon / 2.f);
-    a = (slat * slat) + (cosf(lat1) * cosf(lat2) * slon * slon);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-    return ((2.f * atan2f(sqrtf(a), sqrtf(1.f - a))) * EARTH_RADIUS);
-}
-
-static void
-db_connect()
-{
-    gchar buffer[100];
-    gchar *perror;
-    gchar **pszResult;
-    guint nRow, nColumn;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(_db)
-    {
-        sqlite3_close(_db);
-        _db = NULL;
-    }
-
-    if(!_poi_db)
-        return;
-
-    if(SQLITE_OK != (sqlite3_open(_poi_db, &_db)))
-    {
-        gchar buffer2[200];
-        snprintf(buffer2, sizeof(buffer2),
-                "%s: %s", _("Problem with POI database"),
-                sqlite3_errmsg(_db));
-        sqlite3_close(_db);
-        _db = NULL;
-        popup_error(_window, buffer2);
-        return;
-    }
-
-    if(SQLITE_OK != sqlite3_get_table(_db, "select label from poi limit 1",
-        &pszResult, &nRow, &nColumn, NULL))
-    {
-        gchar *create_sql = sqlite3_mprintf(
-                "create table poi (poi_id integer PRIMARY KEY, lat real, "
-                "lon real, label text, desc text, cat_id integer);"
-                "create table category (cat_id integer PRIMARY KEY,"
-                "label text, desc text, enabled integer);"
-                /* Add some default categories... */
-                "insert into category (label, desc, enabled) "
-                    "values ('%q', '%q', 1); "
-                "insert into category (label, desc, enabled) "
-                    "values ('%q', '%q', 1); "
-                "insert into category (label, desc, enabled) "
-                    "values ('%q', '%q', 1); "
-                "insert into category (label, desc, enabled) "
-                    "values ('%q', '%q', 1); "
-                "insert into category (label, desc, enabled) "
-                    "values ('%q', '%q', 1); "
-                "insert into category (label, desc, enabled) "
-                    "values ('%q', '%q', 1); "
-                "insert into category (label, desc, enabled) "
-                    "values ('%q', '%q', 1); "
-                "insert into category (label, desc, enabled) "
-                    "values ('%q', '%q', 1); "
-                "insert into category (label, desc, enabled) "
-                    "values ('%q', '%q', 1); "
-                "insert into category (label, desc, enabled) "
-                    "values ('%q', '%q', 1); "
-                "insert into category (label, desc, enabled) "
-                    "values ('%q', '%q', 1); ",
-                _("Fuel"),
-                _("Stations for purchasing fuel for vehicles."),
-                _("Residence"),
-                _("Houses, apartments, or other residences of import."),
-                _("Dining"),
-                _("Places to eat or drink."),
-                _("Shopping/Services"),
-                _("Places to shop or acquire services."),
-                _("Recreation"),
-                _("Indoor or Outdoor places to have fun."),
-                _("Transportation"),
-                _("Bus stops, airports, train stations, etc."),
-                _("Lodging"),
-                _("Places to stay temporarily or for the night."),
-                _("School"),
-                _("Elementary schools, college campuses, etc."),
-                _("Business"),
-                _("General places of business."),
-                _("Landmark"),
-                _("General landmarks."),
-                _("Other"),
-                _("Miscellaneous category for everything else."));
-
-        if(SQLITE_OK != sqlite3_exec(_db, create_sql, NULL, NULL, &perror)
-                && (SQLITE_OK != sqlite3_get_table(_db,
-                        "select label from poi limit 1",
-                        &pszResult, &nRow, &nColumn, NULL)))
-        {
-            snprintf(buffer, sizeof(buffer), "%s:\n%s",
-                    _("Failed to open or create database"),
-                    sqlite3_errmsg(_db));
-            sqlite3_close(_db);
-            _db = NULL;
-            popup_error(_window, buffer);
-            return;
-        }
-    }
-    else
-        sqlite3_free_table(pszResult);
-
-    /* Prepare our SQL statements. */
-    /* select from poi */
-    sqlite3_prepare(_db,
-                    "select p.lat, p.lon, p.poi_id, p.label, p.desc,"
-                    " p.cat_id, c.label, c.desc"
-                    " from poi p, category c "
-                    " where p.lat between ? and ? "
-                    " and p.lon between ? and ? "
-                    " and c.enabled = 1 and p.cat_id = c.cat_id",
-                    -1, &_stmt_select_poi, NULL);
-
-    /* select nearest pois */
-    sqlite3_prepare(_db,
-                    "select p.poi_id, p.cat_id, p.lat, p.lon,"
-                    " p.label, p.desc, c.label"
-                    " from poi p, category c "
-                    " where c.enabled = 1 and p.cat_id = c.cat_id"
-                    " order by (($LAT - p.lat) * ($LAT - p.lat) "
-                             "+ ($LON - p.lon) * ($LON - p.lon)) limit 1",
-                    -1, &_stmt_select_nearest_poi, NULL);
-
-    /* insert poi */
-    sqlite3_prepare(_db,
-                        "insert into poi (lat, lon, label, desc, cat_id)"
-                        " values (?, ?, ?, ?, ?)",
-                    -1, &_stmt_insert_poi, NULL);
-    /* update poi */
-    sqlite3_prepare(_db,
-                        "update poi set lat = ?, lon = ?, "
-                        "label = ?, desc = ?, cat_id = ? where poi_id = ?",
-                    -1, &_stmt_update_poi, NULL);
-    /* delete from poi */
-    sqlite3_prepare(_db,
-                    " delete from poi where poi_id = ?",
-                    -1, &_stmt_delete_poi, NULL);
-    /* delete from poi by cat_id */
-    sqlite3_prepare(_db,
-                    "delete from poi where cat_id = ?",
-                    -1, &_stmt_delete_poi_by_catid, NULL);
-    /* get next poilabel */
-    sqlite3_prepare(_db,
-                    "select ifnull(max(poi_id) + 1,1) from poi",
-                    -1, &_stmt_nextlabel_poi, NULL);
-
-    /* select from category */
-    sqlite3_prepare(_db,
-                    "select c.label, c.desc, c.enabled"
-                    " from category c where c.cat_id = ?",
-                    -1, &_stmt_select_cat, NULL);
-    /* insert into category */
-    sqlite3_prepare(_db,
-                    "insert into category (label, desc, enabled)"
-                    " values (?, ?, ?)",
-                    -1, &_stmt_insert_cat, NULL);
-    /* update category */
-    sqlite3_prepare(_db,
-                    "update category set label = ?, desc = ?,"
-                    " enabled = ? where poi_id = ?",
-                    -1, &_stmt_update_cat, NULL);
-    /* delete from category */
-    sqlite3_prepare(_db,
-                    "delete from category where cat_id = ?",
-                    -1, &_stmt_delete_cat, NULL);
-    /* enable category */
-    sqlite3_prepare(_db,
-                    "update category set enabled = ?"
-                    " where cat_id = ?",
-                    -1, &_stmt_toggle_cat, NULL);
-    /* select all category */
-    sqlite3_prepare(_db,
-                    "select c.cat_id, c.label, c.desc, c.enabled,"
-                    " count(p.poi_id)"
-                    " from category c"
-                    " left outer join poi p on c.cat_id = p.cat_id"
-                    " group by c.cat_id, c.label, c.desc, c.enabled "
-                    " order by c.label",
-                    -1, &_stmt_selall_cat, NULL);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-/**
- * Set the connection state.  This function controls all connection-related
- * banners.
- */
-static void
-set_conn_state(ConnState new_conn_state)
-{
-    printf("%s(%d)\n", __PRETTY_FUNCTION__, new_conn_state);
-
-    switch(_conn_state = new_conn_state)
-    {
-        case RCVR_OFF:
-        case RCVR_FIXED:
-            if(_connect_banner)
-            {
-                gtk_widget_destroy(_connect_banner);
-                _connect_banner = NULL;
-            }
-            if(_fix_banner)
-            {
-                gtk_widget_destroy(_fix_banner);
-                _fix_banner = NULL;
-            }
-            break;
-        case RCVR_DOWN:
-            if(_fix_banner)
-            {
-                gtk_widget_destroy(_fix_banner);
-                _fix_banner = NULL;
-            }
-            if(!_connect_banner)
-                _connect_banner = hildon_banner_show_animation(
-                        _window, NULL, _("Searching for GPS receiver"));
-            break;
-        case RCVR_UP:
-            if(_connect_banner)
-            {
-                gtk_widget_destroy(_connect_banner);
-                _connect_banner = NULL;
-            }
-            if(!_fix_banner)
-                _fix_banner = hildon_banner_show_progress(
-                        _window, NULL, _("Establishing GPS fix"));
-            break;
-        default: ; /* to quell warning. */
-    }
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-/**
- * Updates _near_point, _next_way, and _next_wpt.  If quick is FALSE (as
- * it is when this function is called from route_find_nearest_point), then
- * the entire list (starting from _near_point) is searched.  Otherwise, we
- * stop searching when we find a point that is farther away.
- */
-static gboolean
-route_update_nears(gboolean quick)
-{
-    gboolean ret = FALSE;
-    Point *curr, *near;
-    WayPoint *wcurr, *wnext;
-    guint64 near_dist_squared;
-    printf("%s(%d)\n", __PRETTY_FUNCTION__, quick);
-
-    /* If we have waypoints (_next_way != NULL), then determine the "next
-     * waypoint", which is defined as the waypoint after the nearest point,
-     * UNLESS we've passed that waypoint, in which case the waypoint after
-     * that waypoint becomes the "next" waypoint. */
-    if(_next_way)
-    {
-        /* First, set near_dist_squared with the new distance from
-         * _near_point. */
-        near = _near_point;
-        near_dist_squared = DISTANCE_SQUARED(_pos, *near);
-
-        /* Now, search _route for a closer point.  If quick is TRUE, then we'll
-         * only search forward, only as long as we keep finding closer points.
-         */
-        for(curr = _near_point; curr++ != _route.tail; )
-        {
-            if(curr->unity)
-            {
-                guint dist_squared = DISTANCE_SQUARED(_pos, *curr);
-                if(dist_squared <= near_dist_squared)
-                {
-                    near = curr;
-                    near_dist_squared = dist_squared;
-                }
-                else if(quick)
-                    break;
-            }
-        }
-
-        /* Update _near_point. */
-        _near_point = near;
-        _near_point_dist_squared = near_dist_squared;
-
-        for(wnext = wcurr = _next_way; wcurr != _route.wtail; wcurr++)
-        {
-            if(wcurr->point < near
-            /* Okay, this else if expression warrants explanation.  If the
-             * nearest track point happens to be a waypoint, then we want to
-             * check if we have "passed" that waypoint.  To check this, we
-             * test the distance from _pos to the waypoint and from _pos to
-             * _next_wpt, and if the former is increasing and the latter is
-             * decreasing, then we have passed the waypoint, and thus we
-             * should skip it.  Note that if there is no _next_wpt, then
-             * there is no next waypoint, so we do not skip it in that case. */
-                || (wcurr->point == near && quick
-                    && (_next_wpt
-                     && (DISTANCE_SQUARED(_pos, *near) > _next_way_dist_squared
-                      && DISTANCE_SQUARED(_pos, *_next_wpt)
-                                                   < _next_wpt_dist_squared))))
-                wnext = wcurr + 1;
-            else
-                break;
-        }
-
-        if(wnext == _route.wtail && (wnext->point < near
-                || (wnext->point == near && quick
-                    && (_next_wpt
-                     && (DISTANCE_SQUARED(_pos, *near) > _next_way_dist_squared
-                      &&DISTANCE_SQUARED(_pos, *_next_wpt)
-                                                 < _next_wpt_dist_squared)))))
-        {
-            _next_way = NULL;
-            _next_wpt = NULL;
-            _next_way_dist_squared = -1;
-            _next_wpt_dist_squared = -1;
-            ret = TRUE;
-        }
-        /* Only update _next_way (and consequently _next_wpt) if _next_way is
-         * different, and record that fact for return. */
-        else
-        {
-            if(!quick || _next_way != wnext)
-            {
-                _next_way = wnext;
-                _next_wpt = wnext->point;
-                if(_next_wpt == _route.tail)
-                    _next_wpt = NULL;
-                else
-                {
-                    while(!(++_next_wpt)->unity)
-                    {
-                        if(_next_wpt == _route.tail)
-                        {
-                            _next_wpt = NULL;
-                            break;
-                        }
-                    }
-                }
-                ret = TRUE;
-            }
-            _next_way_dist_squared = DISTANCE_SQUARED(_pos, *wnext->point);
-            if(_next_wpt)
-                _next_wpt_dist_squared = DISTANCE_SQUARED(_pos, *_next_wpt);
-        }
-    }
-
-    vprintf("%s(): return %d\n", __PRETTY_FUNCTION__, ret);
-    return ret;
-}
-
-/**
- * Reset the _near_point data by searching the entire route for the nearest
- * route point and waypoint.
- */
-static void
-route_find_nearest_point()
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    /* Initialize _near_point to first non-zero point. */
-    _near_point = _route.head;
-    while(!_near_point->unity && _near_point != _route.tail)
-        _near_point++;
-
-    /* Initialize _next_way. */
-    if(_route.wtail == _route.whead - 1
-            || (_autoroute_data.enabled && _route.wtail == _route.whead))
-        _next_way = NULL;
-    else
-        /* We have at least one waypoint. */
-        _next_way = (_autoroute_data.enabled ? _route.whead+1 : _route.whead);
-    _next_way_dist_squared = -1;
-
-    /* Initialize _next_wpt. */
-    _next_wpt = NULL;
-    _next_wpt_dist_squared = -1;
-
-    route_update_nears(FALSE);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-/**
- * Show the distance from the current GPS location to the given point,
- * following the route.  If point is NULL, then the distance is shown to the
- * next waypoint.
- */
-static gboolean
-route_show_distance_to(Point *point)
-{
-    gchar buffer[80];
-    gfloat lat1, lon1, lat2, lon2;
-    gdouble sum = 0.0;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    /* If point is NULL, use the next waypoint. */
-    if(point == NULL && _next_way)
-        point = _next_way->point;
-
-    /* If point is still NULL, return an error. */
-    if(point == NULL)
-    {
-        printf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
-        return FALSE;
-    }
-
-    unit2latlon(_pos.unitx, _pos.unity, lat1, lon1);
-    if(point > _near_point)
-    {
-        Point *curr;
-        /* Skip _near_point in case we have already passed it. */
-        for(curr = _near_point + 1; curr <= point; ++curr)
-        {
-            if(curr->unity)
-            {
-                unit2latlon(curr->unitx, curr->unity, lat2, lon2);
-                sum += calculate_distance(lat1, lon1, lat2, lon2);
-                lat1 = lat2;
-                lon1 = lon2;
-            }
-        }
-    }
-    else if(point < _near_point)
-    {
-        Point *curr;
-        /* Skip _near_point in case we have already passed it. */
-        for(curr = _near_point - 1; curr >= point; --curr)
-        {
-            if(curr->unity)
-            {
-                unit2latlon(curr->unitx, curr->unity, lat2, lon2);
-                sum += calculate_distance(lat1, lon1, lat2, lon2);
-                lat1 = lat2;
-                lon1 = lon2;
-            }
-        }
-    }
-    else
-    {
-        /* Waypoint _is_ the nearest point. */
-        unit2latlon(_near_point->unitx, _near_point->unity, lat2, lon2);
-        sum += calculate_distance(lat1, lon1, lat2, lon2);
-    }
-
-    snprintf(buffer, sizeof(buffer), "%s: %.02f %s", _("Distance"),
-            sum * UNITS_CONVERT[_units], UNITS_TEXT[_units]);
-    MACRO_BANNER_SHOW_INFO(_window, buffer);
-
-    return TRUE;
-    printf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-}
-
-static void
-route_show_distance_to_next()
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(!route_show_distance_to(NULL))
-    {
-        MACRO_BANNER_SHOW_INFO(_window, _("There is no next waypoint."));
-    }
-    printf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static void
-route_show_distance_to_last()
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(_route.head != _route.tail)
-    {
-        /* Find last non-zero point. */
-        Point *p;
-        for(p = _route.tail; !p->unity; p--) { }
-        route_show_distance_to(p);
-    }
-    else
-    {
-        MACRO_BANNER_SHOW_INFO(_window, _("The current route is empty."));
-    }
-    printf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static void
-track_show_distance_from(Point *point)
-{
-    gchar buffer[80];
-    gfloat lat1, lon1, lat2, lon2;
-    gdouble sum = 0.0;
-    Point *curr;
-    unit2latlon(_pos.unitx, _pos.unity, lat1, lon1);
-
-    /* Skip _track.tail because that should be _pos. */
-    for(curr = _track.tail; curr > point; --curr)
-    {
-        if(curr->unity)
-        {
-            unit2latlon(curr->unitx, curr->unity, lat2, lon2);
-            sum += calculate_distance(lat1, lon1, lat2, lon2);
-            lat1 = lat2;
-            lon1 = lon2;
-        }
-    }
-
-    snprintf(buffer, sizeof(buffer), "%s: %.02f %s", _("Distance"),
-            sum * UNITS_CONVERT[_units], UNITS_TEXT[_units]);
-    MACRO_BANNER_SHOW_INFO(_window, buffer);
-}
-
-static void
-track_show_distance_from_last()
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    /* Find last zero point. */
-    if(_track.head != _track.tail)
-    {
-        Point *point;
-        /* Find last zero point. */
-        for(point = _track.tail; point->unity; point--) { }
-        track_show_distance_from(point);
-    }
-    else
-    {
-        MACRO_BANNER_SHOW_INFO(_window, _("The current track is empty."));
-    }
-    printf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static void
-track_show_distance_from_first()
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    /* Find last zero point. */
-    if(_track.head != _track.tail)
-        track_show_distance_from(_track.head);
-    else
-    {
-        MACRO_BANNER_SHOW_INFO(_window, _("The current track is empty."));
-    }
-    printf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-
-/**
- * Render a single track line to _map_pixmap.  If either point on the line
- * is a break (defined as unity == 0), a circle is drawn at the other point.
- * IT IS AN ERROR FOR BOTH POINTS TO INDICATE A BREAK.
- */
-static void
-map_render_segment(GdkGC *gc_norm, GdkGC *gc_alt,
-        guint unitx1, guint unity1, guint unitx2, guint unity2)
-{
-    vprintf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(!unity1)
-    {
-        guint x2, y2;
-        x2 = unit2bufx(unitx2);
-        y2 = unit2bufy(unity2);
-        /* Make sure this circle will be visible. */
-        if((x2 < BUF_WIDTH_PIXELS)
-                && (y2 < BUF_HEIGHT_PIXELS))
-            gdk_draw_arc(_map_pixmap, gc_alt,
-                    FALSE, /* FALSE: not filled. */
-                    x2 - _draw_width,
-                    y2 - _draw_width,
-                    2 * _draw_width,
-                    2 * _draw_width,
-                    0, /* start at 0 degrees. */
-                    360 * 64);
-    }
-    else if(!unity2)
-    {
-        guint x1, y1;
-        x1 = unit2bufx(unitx1);
-        y1 = unit2bufy(unity1);
-        /* Make sure this circle will be visible. */
-        if((x1 < BUF_WIDTH_PIXELS)
-                && ((unsigned)y1 < BUF_HEIGHT_PIXELS))
-            gdk_draw_arc(_map_pixmap, gc_alt,
-                    FALSE, /* FALSE: not filled. */
-                    x1 - _draw_width,
-                    y1 - _draw_width,
-                    2 * _draw_width,
-                    2 * _draw_width,
-                    0, /* start at 0 degrees. */
-                    360 * 64);
-    }
-    else
-    {
-        gint x1, y1, x2, y2;
-        x1 = unit2bufx(unitx1);
-        y1 = unit2bufy(unity1);
-        x2 = unit2bufx(unitx2);
-        y2 = unit2bufy(unity2);
-        /* Make sure this line could possibly be visible. */
-        if(!((x1 > BUF_WIDTH_PIXELS && x2 > BUF_WIDTH_PIXELS)
-                || (x1 < 0 && x2 < 0)
-                || (y1 > BUF_HEIGHT_PIXELS && y2 > BUF_HEIGHT_PIXELS)
-                || (y1 < 0 && y2 < 0)))
-            gdk_draw_line(_map_pixmap, gc_norm, x1, y1, x2, y2);
-    }
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-/**
- * Render all track data onto the _map_pixmap.  Note that this does not
- * clear the pixmap of previous track data (use map_force_redraw() for
- * that), and also note that this method does not queue any redraws, so it
- * is up to the caller to decide which part of the track really needs to be
- * redrawn.
- */
-static void
-map_render_path(Path *path, GdkGC **gc)
-{
-    Point *curr;
-    WayPoint *wcurr;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    /* gc is a pointer to the first GC to use (for plain points).  (gc + 1)
-     * is a pointer to the GC to use for waypoints, and (gc + 2) is a pointer
-     * to the GC to use for breaks. */
-
-    /* else there is a route to draw. */
-    for(curr = path->head, wcurr = path->whead; curr++ != path->tail; )
-    {
-        /* Draw the line from (curr - 1) to (curr). */
-        map_render_segment(gc[0], gc[2],
-                curr[-1].unitx, curr[-1].unity, curr->unitx, curr->unity);
-
-        /* Now, check if curr is a waypoint. */
-        if(wcurr && wcurr <= path->wtail && wcurr->point == curr)
-        {
-            guint x1 = unit2bufx(wcurr->point->unitx);
-            guint y1 = unit2bufy(wcurr->point->unity);
-            if((x1 < BUF_WIDTH_PIXELS)
-                    && (y1 < BUF_HEIGHT_PIXELS))
-            {
-                gdk_draw_arc(_map_pixmap,
-                        gc[1],
-                        FALSE, /* FALSE: not filled. */
-                        x1 - _draw_width,
-                        y1 - _draw_width,
-                        2 * _draw_width,
-                        2 * _draw_width,
-                        0, /* start at 0 degrees. */
-                        360 * 64);
-            }
-            wcurr++;
-        }
-    }
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static void
-map_render_paths()
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if((_show_tracks & ROUTES_MASK) && _route.head != _route.tail)
-    {
-        map_render_path(&_route, _gc + COLORABLE_ROUTE);
-
-        /* Now, draw the next waypoint on top of all other waypoints. */
-        if(_next_way)
-        {
-            guint x1 = unit2bufx(_next_way->point->unitx);
-            guint y1 = unit2bufy(_next_way->point->unity);
-            if((x1 < BUF_WIDTH_PIXELS)
-                    && (y1 < BUF_HEIGHT_PIXELS))
-            {
-                /* Draw the next waypoint as a break. */
-                gdk_draw_arc(_map_pixmap,
-                        _gc[COLORABLE_ROUTE_BREAK],
-                        FALSE, /* FALSE: not filled. */
-                        x1 - _draw_width,
-                        y1 - _draw_width,
-                        2 * _draw_width,
-                        2 * _draw_width,
-                        0, /* start at 0 degrees. */
-                        360 * 64);
-            }
-        }
-    }
-    if(_show_tracks & TRACKS_MASK)
-        map_render_path(&_track, _gc + COLORABLE_TRACK);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-/**
- * Add a point to the _track list.  This function is slightly overloaded,
- * since it is what houses the check for "have we moved
- * significantly": it also initiates the re-calculation of the _near_point
- * data, as well as calling osso_display_state_on() when we have the focus.
- *
- * If a non-zero time is given, then the current position (as taken from the
- * _pos variable) is appended to _track with the given time.  If time is zero,
- * then _point_null is appended to _track with time zero (this produces a
- * "break" in the track).
- */
-static void
-track_add(time_t time, gboolean newly_fixed)
-{
-    gboolean show_directions = TRUE;
-    gint announce_thres_unsquared;
-    printf("%s(%u, %u)\n", __PRETTY_FUNCTION__, _pos.unitx, _pos.unity);
-
-    if(abs((gint)_pos.unitx - _track.tail->unitx) > _draw_width
-    || abs((gint)_pos.unity - _track.tail->unity) > _draw_width)
-    {
-        /* If time != 0, update the nearest-waypoint data. */
-        if(time && _route.head != _route.tail
-                && (newly_fixed ? (route_find_nearest_point(), TRUE)
-                                : route_update_nears(TRUE)))
-        {
-            /* Nearest waypoint has changed - re-render paths. */
-            map_render_paths();
-            MACRO_QUEUE_DRAW_AREA();
-        }
-        if(_show_tracks & TRACKS_MASK)
-        {
-            /* Instead of calling map_render_paths(), we'll draw the new line
-             * ourselves and call gtk_widget_queue_draw_area(). */
-            gint tx1, ty1, tx2, ty2;
-            map_render_segment(_gc[COLORABLE_TRACK],
-                    _gc[COLORABLE_TRACK_BREAK],
-                    _track.tail->unitx, _track.tail->unity,
-                    _pos.unitx, _pos.unity);
-            if(time && _track.tail->unity)
-            {
-                tx1 = unit2x(_track.tail->unitx);
-                ty1 = unit2y(_track.tail->unity);
-                tx2 = unit2x(_pos.unitx);
-                ty2 = unit2y(_pos.unity);
-                gtk_widget_queue_draw_area(_map_widget,
-                        MIN(tx1, tx2) - _draw_width,
-                        MIN(ty1, ty2) - _draw_width,
-                        abs(tx1 - tx2) + (2 * _draw_width),
-                        abs(ty1 - ty2) + (2 * _draw_width));
-            }
-        }
-        MACRO_PATH_INCREMENT_TAIL(_track);
-
-        if(time)
-            *_track.tail = _pos;
-        else
-            *_track.tail = _point_null;
-
-        if(_autoroute_data.enabled && !_autoroute_data.in_progress
-                && _near_point_dist_squared > (200 * 200))
-        {
-            MACRO_BANNER_SHOW_INFO(_window,
-                    _("Recalculating directions..."));
-            _autoroute_data.in_progress = TRUE;
-            show_directions = FALSE;
-            g_idle_add((GSourceFunc)auto_route_dl_idle, NULL);
-        }
-
-        /* Keep the display on. */
-        KEEP_DISPLAY_ON();
-    }
-
-    announce_thres_unsquared = (20 + (guint)_gps.speed)
-        * _announce_notice_ratio * 3;
-    /* Check if we should announce upcoming waypoints. */
-    if(show_directions && time && _next_way_dist_squared
-            < (announce_thres_unsquared * announce_thres_unsquared))
-    {
-        if(_enable_voice && strcmp(_next_way->desc, _last_spoken_phrase))
-        {
-            g_free(_last_spoken_phrase);
-            _last_spoken_phrase = g_strdup(_next_way->desc);
-            if(!fork())
-            {
-                /* We are the fork child.  Synthesize the voice. */
-                hildon_play_system_sound(
-                        "/usr/share/sounds/ui-information_note.wav");
-                sleep(1);
-#               define _voice_synth_path "/usr/bin/flite"
-                printf("%s %s\n", _voice_synth_path, _last_spoken_phrase);
-                execl(_voice_synth_path, _voice_synth_path,
-                        "-t", _last_spoken_phrase, (char *)NULL);
-                exit(0);
-            }
-        }
-        MACRO_BANNER_SHOW_INFO(_window, _next_way->desc);
-    }
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static void
-track_clear()
-{
-    GtkWidget *confirm;
-
-    confirm = hildon_note_new_confirmation(GTK_WINDOW(_window),
-                            _("Really clear the track?"));
-
-    if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm))) {
-        _track.tail = _track.head;
-        map_force_redraw();
-    }
-
-    gtk_widget_destroy(confirm);
-}
-
-static void
-track_insert_break()
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(_track.tail->unity)
-    {
-        guint x1, y1;
-
-        /* To mark a "waypoint" in a track, we'll add a (0, 0) point and then
-         * another instance of the most recent track point. */
-        MACRO_PATH_INCREMENT_TAIL(_track);
-        *_track.tail = _point_null;
-        MACRO_PATH_INCREMENT_TAIL(_track);
-        *_track.tail = _track.tail[-2];
-
-        /** Instead of calling map_render_paths(), we'll just add the waypoint
-         * ourselves. */
-        x1 = unit2bufx(_track.tail->unitx);
-        y1 = unit2bufy(_track.tail->unity);
-        /* Make sure this circle will be visible. */
-        if((x1 < BUF_WIDTH_PIXELS)
-                && ((unsigned)y1 < BUF_HEIGHT_PIXELS))
-            gdk_draw_arc(_map_pixmap, _gc[COLORABLE_TRACK_BREAK],
-                    FALSE, /* FALSE: not filled. */
-                    x1 - _draw_width,
-                    y1 - _draw_width,
-                    2 * _draw_width,
-                    2 * _draw_width,
-                    0, /* start at 0 degrees. */
-                    360 * 64);
-    }
-    else
-    {
-        MACRO_BANNER_SHOW_INFO(_window, _("Break already inserted."));
-    }
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-/**
- * Disconnect from the receiver.  This method cleans up any and everything
- * that might be associated with the receiver.
- */
-static void
-rcvr_disconnect()
-{
-    GError *error = NULL;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    /* Remove watches. */
-    if(_clater_sid)
-    {
-        g_source_remove(_clater_sid);
-        _clater_sid = 0;
-    }
-    if(_error_sid)
-    {
-        g_source_remove(_error_sid);
-        _error_sid = 0;
-    }
-    if(_connect_sid)
-    {
-        g_source_remove(_connect_sid);
-        _connect_sid = 0;
-    }
-    if(_input_sid)
-    {
-        g_source_remove(_input_sid);
-        _input_sid = 0;
-    }
-
-    /* Destroy the GIOChannel object. */
-    if(_channel)
-    {
-        g_io_channel_shutdown(_channel, FALSE, NULL);
-        g_io_channel_unref(_channel);
-        _channel = NULL;
-    }
-
-    /* Close the file descriptor. */
-    if(_fd != -1)
-    {
-        close(_fd);
-        _fd = -1;
-    }
-
-    if(_rfcomm_req_proxy)
-    {
-        dbus_g_proxy_call(_rfcomm_req_proxy, BTCOND_RFCOMM_CANCEL_CONNECT_REQ,
-                    &error,
-                    G_TYPE_STRING, _rcvr_mac,
-                    G_TYPE_STRING, "SPP",
-                    G_TYPE_INVALID,
-                    G_TYPE_INVALID);
-        error = NULL;
-        dbus_g_proxy_call(_rfcomm_req_proxy, BTCOND_RFCOMM_DISCONNECT_REQ,
-                    &error,
-                    G_TYPE_STRING, _rcvr_mac,
-                    G_TYPE_STRING, "SPP",
-                    G_TYPE_INVALID,
-                    G_TYPE_INVALID);
-    }
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static void rcvr_connect_later(); /* Forward declaration. */
-
-static void
-rcvr_connect_fd(gchar *fdpath)
-{
-    printf("%s(%s)\n", __PRETTY_FUNCTION__, fdpath);
-
-    /* Create the file descriptor. */
-
-    /* If file descriptor creation failed, try again later. */
-    if(-1 == (_fd = open(fdpath, O_RDONLY)))
-    {
-        rcvr_disconnect();
-        rcvr_connect_later();
-    }
-    else
-    {
-        /* Reset GPS read buffer */
-        _gps_read_buf_curr = _gps_read_buf;
-        *_gps_read_buf_curr = '\0';
-
-        /* Create channel and add watches. */
-        _channel = g_io_channel_unix_new(_fd);
-        g_io_channel_set_flags(_channel, G_IO_FLAG_NONBLOCK, NULL);
-        _error_sid = g_io_add_watch_full(_channel, G_PRIORITY_HIGH_IDLE,
-                G_IO_ERR | G_IO_HUP, channel_cb_error, NULL, NULL);
-        _connect_sid = g_io_add_watch_full(_channel, G_PRIORITY_HIGH_IDLE,
-                G_IO_OUT, channel_cb_connect, NULL, NULL);
-    }
-    g_free(fdpath);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static void
-rcvr_connect_response(DBusGProxy *proxy, DBusGProxyCall *call_id)
-{
-    GError *error = NULL;
-    gchar *fdpath = NULL;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(_conn_state == RCVR_DOWN && _rcvr_mac)
-    {
-        if(!dbus_g_proxy_end_call(_rfcomm_req_proxy, call_id, &error,
-                    G_TYPE_STRING, &fdpath, G_TYPE_INVALID))
-        {
-            if(error->domain == DBUS_GERROR
-                    && error->code == DBUS_GERROR_REMOTE_EXCEPTION)
-            {
-                /* If we're already connected, it's not an error, unless
-                 * they don't give us the file descriptor path, in which
-                 * case we re-connect.*/
-                if(!strcmp(BTCOND_ERROR_CONNECTED,
-                            dbus_g_error_get_name(error)) || !fdpath)
-                {
-                    GtkWidget *confirm;
-                    printf("Caught remote method exception %s: %s",
-                            dbus_g_error_get_name(error),
-                            error->message);
-                    rcvr_disconnect();
-
-                    /* Ask user to re-connect. */
-                    confirm = hildon_note_new_confirmation(GTK_WINDOW(_window),
-                            _("Failed to connect to GPS receiver.  Retry?"));
-
-                    if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm)))
-                        rcvr_connect_later(); /* Try again later. */
-                    else
-                        set_conn_state(RCVR_OFF);
-
-                    gtk_widget_destroy(confirm);
-                    return;
-                }
-            }
-            else
-            {
-                /* Unknown error. */
-                g_printerr("Error: %s\n", error->message);
-                rcvr_disconnect();
-                rcvr_connect_later(); /* Try again later. */
-                return;
-            }
-        }
-        rcvr_connect_fd(fdpath);
-    }
-    /* else { Looks like the middle of a disconnect.  Do nothing. } */
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-/**
- * Connect to the receiver.
- * This method assumes that _fd is -1 and _channel is NULL.  If unsure, call
- * rcvr_disconnect() first.
- * Since this is an idle function, this function returns whether or not it
- * should be called again, which is always FALSE.
- */
-static gboolean
-rcvr_connect_now()
-{
-    printf("%s(%d)\n", __PRETTY_FUNCTION__, _conn_state);
-
-    if(_conn_state == RCVR_DOWN && _rcvr_mac)
-    {
-#ifndef DEBUG
-        if(*_rcvr_mac != '/')
-        {
-            if(_rfcomm_req_proxy)
-            {
-                gint mybool = TRUE;
-                dbus_g_proxy_begin_call(
-                        _rfcomm_req_proxy, BTCOND_RFCOMM_CONNECT_REQ,
-                        (DBusGProxyCallNotify)rcvr_connect_response,
-                        NULL, NULL,
-                        G_TYPE_STRING, _rcvr_mac,
-                        G_TYPE_STRING, "SPP",
-                        G_TYPE_BOOLEAN, &mybool,
-                        G_TYPE_INVALID);
-            }
-        }
-        else
-            rcvr_connect_fd(g_strdup(_rcvr_mac));
-
-#else
-        /* We're in DEBUG mode, so instead of connecting, skip to FIXED. */
-        printf("FIXED!\n");
-        set_conn_state(RCVR_FIXED);
-#endif
-    }
-
-    _clater_sid = 0;
-
-    vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
-    return FALSE;
-}
-
-/**
- * Place a request to connect about 1 second after the function is called.
- */
-static void
-rcvr_connect_later()
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    _clater_sid = g_timeout_add(1000, (GSourceFunc)rcvr_connect_now, NULL);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-/**
- * Convert the float lat/lon/speed/heading data into integer units.
- */
-static void
-integerize_data()
-{
-    gfloat tmp;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    latlon2unit(_gps.lat, _gps.lon, _pos.unitx, _pos.unity);
-
-    tmp = (_gps.heading * (1.f / 180.f)) * PI;
-    _vel_offsetx = (gint)(floorf(_gps.speed * sinf(tmp) + 0.5f));
-    _vel_offsety = -(gint)(floorf(_gps.speed * cosf(tmp) + 0.5f));
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-/**
- * Update all GdkGC objects to reflect the current _draw_width.
- */
-#define UPDATE_GC(gc) \
-    gdk_gc_set_line_attributes(gc, \
-            _draw_width, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
-static void
-update_gcs()
-{
-    gint i;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    for(i = 0; i < COLORABLE_ENUM_COUNT; i++)
-    {
-        gdk_color_alloc(gtk_widget_get_colormap(_map_widget), &_color[i]);
-        if(_gc[i])
-            g_object_unref(_gc[i]);
-        _gc[i] = gdk_gc_new(_map_pixmap);
-        gdk_gc_set_foreground(_gc[i], &_color[i]);
-        gdk_gc_set_line_attributes(_gc[i],
-                _draw_width, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
-    }
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-/**
- * Save all configuration data to GCONF.
- */
-static void
-config_save()
-{
-    gchar *config_dir;
-    GConfClient *gconf_client = gconf_client_get_default();
-    gchar buffer[16];
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(!gconf_client)
-    {
-        popup_error(_window,
-                _("Failed to initialize GConf.  Settings were not saved."));
-        return;
-    }
-
-    /* Initialize config_dir. */
-    config_dir = gnome_vfs_expand_initial_tilde(CONFIG_DIR_NAME);
-    g_mkdir_with_parents(config_dir, 0700);
-
-    /* Save Receiver MAC from GConf. */
-    if(_rcvr_mac)
-        gconf_client_set_string(gconf_client,
-                GCONF_KEY_RCVR_MAC, _rcvr_mac, NULL);
-    else
-        gconf_client_unset(gconf_client,
-                GCONF_KEY_RCVR_MAC, NULL);
-
-    /* Save Auto-Download. */
-    gconf_client_set_bool(gconf_client,
-            GCONF_KEY_AUTO_DOWNLOAD, _auto_download, NULL);
-
-    /* Save Auto-Center Sensitivity. */
-    gconf_client_set_int(gconf_client,
-            GCONF_KEY_CENTER_SENSITIVITY, _center_ratio, NULL);
-
-    /* Save Auto-Center Lead Amount. */
-    gconf_client_set_int(gconf_client,
-            GCONF_KEY_LEAD_AMOUNT, _lead_ratio, NULL);
-
-    /* Save Draw Line Width. */
-    gconf_client_set_int(gconf_client,
-            GCONF_KEY_DRAW_WIDTH, _draw_width, NULL);
-
-    /* Save Announce Advance Notice Ratio. */
-    gconf_client_set_int(gconf_client,
-            GCONF_KEY_ANNOUNCE_NOTICE, _announce_notice_ratio, NULL);
-
-    /* Save Enable Voice flag. */
-    gconf_client_set_bool(gconf_client,
-            GCONF_KEY_ENABLE_VOICE, _enable_voice, NULL);
-
-    /* Save fullscreen flag. */
-    gconf_client_set_bool(gconf_client,
-            GCONF_KEY_FULLSCREEN, _fullscreen, NULL);
-
-    /* Save Keep On When Fullscreen flag. */
-    gconf_client_set_bool(gconf_client,
-            GCONF_KEY_ALWAYS_KEEP_ON, _always_keep_on, NULL);
-
-    /* Save Units. */
-    gconf_client_set_string(gconf_client,
-            GCONF_KEY_UNITS, UNITS_TEXT[_units], NULL);
-
-    /* Save Custom Key Actions. */
-    {
-        gint i;
-        for(i = 0; i < CUSTOM_KEY_ENUM_COUNT; i++)
-            gconf_client_set_string(gconf_client,
-                    CUSTOM_KEY_GCONF[i],
-                    CUSTOM_ACTION_TEXT[_action[i]], NULL);
-    }
-
-    /* Save Deg Format. */
-    gconf_client_set_string(gconf_client,
-            GCONF_KEY_DEG_FORMAT, DEG_FORMAT_TEXT[_degformat], NULL);
-
-    /* Save Speed Limit On flag. */
-    gconf_client_set_bool(gconf_client,
-            GCONF_KEY_SPEED_LIMIT_ON, _speed_limit_on, NULL);
-
-    /* Save Speed Limit. */
-    gconf_client_set_int(gconf_client,
-            GCONF_KEY_SPEED_LIMIT, _speed_limit, NULL);
-
-    /* Save Speed Location. */
-    gconf_client_set_string(gconf_client,
-            GCONF_KEY_SPEED_LOCATION,
-            SPEED_LOCATION_TEXT[_speed_location], NULL);
-
-    /* Save Info Font Size. */
-    gconf_client_set_string(gconf_client,
-            GCONF_KEY_INFO_FONT_SIZE,
-            INFO_FONT_TEXT[_info_font_size], NULL);
-
-    /* Save last saved latitude. */
-    gconf_client_set_float(gconf_client,
-            GCONF_KEY_LAT, _gps.lat, NULL);
-
-    /* Save last saved longitude. */
-    gconf_client_set_float(gconf_client,
-            GCONF_KEY_LON, _gps.lon, NULL);
-
-    /* Save last center point. */
-    {
-        gfloat center_lat, center_lon;
-        unit2latlon(_center.unitx, _center.unity, center_lat, center_lon);
-
-        /* Save last center latitude. */
-        gconf_client_set_float(gconf_client,
-                GCONF_KEY_CENTER_LAT, center_lat, NULL);
-
-        /* Save last center longitude. */
-        gconf_client_set_float(gconf_client,
-                GCONF_KEY_CENTER_LON, center_lon, NULL);
-    }
-
-    /* Save last Zoom Level. */
-    gconf_client_set_int(gconf_client,
-            GCONF_KEY_ZOOM, _zoom, NULL);
-
-    /* Save Route Directory. */
-    if(_route_dir_uri)
-        gconf_client_set_string(gconf_client,
-                GCONF_KEY_ROUTEDIR, _route_dir_uri, NULL);
-
-    /* Save the repositories. */
-    {
-        GList *curr = _repo_list;
-        GSList *temp_list = NULL;
-        gint curr_repo_index = 0;
-
-        for(curr = _repo_list; curr != NULL; curr = curr->next)
-        {
-            /* Build from each part of a repo, delimited by newline characters:
-             * 1. url
-             * 2. cache_dir
-             * 3. dl_zoom_steps
-             * 4. view_zoom_steps
-             */
-            RepoData *rd = curr->data;
-            gchar buffer[BUFFER_SIZE];
-            snprintf(buffer, sizeof(buffer),
-                    "%s\t%s\t%s\t%d\t%d\t%d\t%d",
-                    rd->name,
-                    rd->url,
-                    rd->cache_dir,
-                    rd->dl_zoom_steps,
-                    rd->view_zoom_steps,
-                    rd->double_size,
-                    rd->nextable);
-            temp_list = g_slist_append(temp_list, g_strdup(buffer));
-            if(rd == _curr_repo)
-                gconf_client_set_int(gconf_client,
-                        GCONF_KEY_CURRREPO, curr_repo_index, NULL);
-            curr_repo_index++;
-        }
-        gconf_client_set_list(gconf_client,
-                GCONF_KEY_REPOSITORIES, GCONF_VALUE_STRING, temp_list, NULL);
-    }
-
-    /* Save Last Track File. */
-    if(_track_file_uri)
-        gconf_client_set_string(gconf_client,
-                GCONF_KEY_TRACKFILE, _track_file_uri, NULL);
-
-    /* Save Auto-Center Mode. */
-    gconf_client_set_int(gconf_client,
-            GCONF_KEY_AUTOCENTER_MODE, _center_mode, NULL);
-
-    /* Save Show Zoom Level flag. */
-    gconf_client_set_bool(gconf_client,
-            GCONF_KEY_SHOWZOOMLEVEL, _show_zoomlevel, NULL);
-
-    /* Save Show Scale flag. */
-    gconf_client_set_bool(gconf_client,
-            GCONF_KEY_SHOWSCALE, _show_scale, NULL);
-
-    /* Save Show Tracks flag. */
-    gconf_client_set_bool(gconf_client,
-            GCONF_KEY_SHOWTRACKS, _show_tracks & TRACKS_MASK, NULL);
-
-    /* Save Show Routes flag. */
-    gconf_client_set_bool(gconf_client,
-            GCONF_KEY_SHOWROUTES, _show_tracks & ROUTES_MASK, NULL);
-
-    /* Save Show Velocity Vector flag. */
-    gconf_client_set_bool(gconf_client,
-            GCONF_KEY_SHOWVELVEC, _show_velvec, NULL);
-
-    /* Save Show POIs flag. */
-    gconf_client_set_bool(gconf_client,
-            GCONF_KEY_SHOWPOIS, _show_poi, NULL);
-
-    /* Save Enable GPS flag. */
-    gconf_client_set_bool(gconf_client,
-            GCONF_KEY_ENABLE_GPS, _enable_gps, NULL);
-
-    /* Save Route Locations. */
-    gconf_client_set_list(gconf_client,
-            GCONF_KEY_ROUTE_LOCATIONS, GCONF_VALUE_STRING, _loc_list, NULL);
-
-    /* Save GPS Info flag. */
-    gconf_client_set_bool(gconf_client,
-            GCONF_KEY_GPS_INFO, _gps_info, NULL);
-
-    /* Save Route Download URL Format. */
-    gconf_client_set_string(gconf_client,
-            GCONF_KEY_ROUTE_DL_URL, _route_dl_url, NULL);
-
-    /* Save Route Download Radius. */
-    gconf_client_set_int(gconf_client,
-            GCONF_KEY_ROUTE_DL_RADIUS, _route_dl_radius, NULL);
-
-    /* Save Colors. */
-    {
-        gint i;
-        for(i = 0; i < COLORABLE_ENUM_COUNT; i++)
-        {
-            snprintf(buffer, sizeof(buffer), "#%02x%02x%02x",
-                    _color[i].red >> 8,
-                    _color[i].green >> 8,
-                    _color[i].blue >> 8);
-            gconf_client_set_string(gconf_client,
-                    COLORABLE_GCONF[i], buffer, NULL);
-        }
-    }
-
-    /* Save POI database. */
-    if(_poi_db)
-        gconf_client_set_string(gconf_client,
-                GCONF_KEY_POI_DB, _poi_db, NULL);
-    else
-        gconf_client_unset(gconf_client, GCONF_KEY_POI_DB, NULL);
-
-    /* Save Show POI below zoom. */
-    gconf_client_set_int(gconf_client,
-            GCONF_KEY_POI_ZOOM, _poi_zoom, NULL);
-
-    /* Save route. */
-    {
-        GnomeVFSHandle *handle;
-        gchar *route_file;
-        route_file = gnome_vfs_uri_make_full_from_relative(
-                config_dir, CONFIG_FILE_ROUTE);
-        if(GNOME_VFS_OK == gnome_vfs_create(&handle, route_file,
-                    GNOME_VFS_OPEN_WRITE, FALSE, 0600))
-        {
-            write_gpx(&_route, handle);
-            gnome_vfs_close(handle);
-        }
-        g_free(route_file);
-    }
-
-    /* Save track. */
-    {
-        GnomeVFSHandle *handle;
-        gchar *track_file;
-        track_file = gnome_vfs_uri_make_full_from_relative(
-                config_dir, CONFIG_FILE_TRACK);
-        if(GNOME_VFS_OK == gnome_vfs_create(&handle, track_file,
-                    GNOME_VFS_OPEN_WRITE, FALSE, 0600))
-        {
-            write_gpx(&_track, handle);
-            gnome_vfs_close(handle);
-        }
-        g_free(track_file);
-    }
-
-    gconf_client_clear_cache(gconf_client);
-    g_object_unref(gconf_client);
-    g_free(config_dir);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static void
-force_min_visible_bars(HildonControlbar *control_bar, gint num_bars)
-{
-    GValue val;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-    memset(&val, 0, sizeof(val));
-    g_value_init(&val, G_TYPE_INT);
-    g_value_set_int(&val, num_bars);
-    g_object_set_property(G_OBJECT(control_bar), "minimum-visible-bars", &val);
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-
-typedef struct _ScanInfo ScanInfo;
-struct _ScanInfo {
-    GtkWidget *settings_dialog;
-    GtkWidget *txt_rcvr_mac;
-    GtkWidget *scan_dialog;
-    GtkWidget *banner;
-    GtkListStore *store;
-    guint sid;
-    DBusGProxy *req_proxy;
-    DBusGProxy *sig_proxy;
-};
-
-
-static void
-scan_cb_dev_found(DBusGProxy *sig_proxy, const gchar *bda,
-        const gchar *name, gpointer *class, guchar rssi, gint coff,
-        ScanInfo *scan_info)
-{
-    GtkTreeIter iter;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-    gtk_list_store_append(scan_info->store, &iter);
-    gtk_list_store_set(scan_info->store, &iter,
-            0, g_strdup(bda),
-            1, g_strdup(name),
-            -1);
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static void
-scan_cb_search_complete(DBusGProxy *sig_proxy, ScanInfo *scan_info)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-    gtk_widget_destroy(scan_info->banner);
-    dbus_g_proxy_disconnect_signal(sig_proxy, BTSEARCH_DEV_FOUND_SIG,
-            G_CALLBACK(scan_cb_dev_found), scan_info);
-    dbus_g_proxy_disconnect_signal(sig_proxy, BTSEARCH_SEARCH_COMPLETE_SIG,
-            G_CALLBACK(scan_cb_search_complete), scan_info);
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static gint
-scan_start_search(ScanInfo *scan_info)
-{
-    GError *error = NULL;
-    DBusGConnection *dbus_conn;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    /* Initialize D-Bus. */
-    if(NULL == (dbus_conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error)))
-    {
-        g_printerr("Failed to open connection to D-Bus: %s.\n",
-                error->message);
-        return 1;
-    }
-
-    if(NULL == (scan_info->req_proxy = dbus_g_proxy_new_for_name(dbus_conn,
-            BTSEARCH_SERVICE,
-            BTSEARCH_REQ_PATH,
-            BTSEARCH_REQ_INTERFACE)))
-    {
-        g_printerr("Failed to create D-Bus request proxy for btsearch.");
-        return 2;
-    }
-
-    if(NULL == (scan_info->sig_proxy = dbus_g_proxy_new_for_name(dbus_conn,
-            BTSEARCH_SERVICE,
-            BTSEARCH_SIG_PATH,
-            BTSEARCH_SIG_INTERFACE)))
-    {
-        g_printerr("Failed to create D-Bus signal proxy for btsearch.");
-        return 2;
-    }
-
-    dbus_g_object_register_marshaller(
-            g_cclosure_user_marshal_VOID__STRING_STRING_POINTER_UCHAR_UINT,
-            G_TYPE_NONE,
-            G_TYPE_STRING,
-            G_TYPE_STRING,
-            DBUS_TYPE_G_UCHAR_ARRAY,
-            G_TYPE_UCHAR,
-            G_TYPE_UINT,
-            G_TYPE_INVALID);
-
-    dbus_g_proxy_add_signal(scan_info->sig_proxy,
-            BTSEARCH_DEV_FOUND_SIG,
-            G_TYPE_STRING,
-            G_TYPE_STRING,
-            DBUS_TYPE_G_UCHAR_ARRAY,
-            G_TYPE_UCHAR,
-            G_TYPE_UINT,
-            G_TYPE_INVALID);
-    dbus_g_proxy_connect_signal(scan_info->sig_proxy, BTSEARCH_DEV_FOUND_SIG,
-            G_CALLBACK(scan_cb_dev_found), scan_info, NULL);
-
-    dbus_g_proxy_add_signal(scan_info->sig_proxy,
-            BTSEARCH_SEARCH_COMPLETE_SIG,
-            G_TYPE_INVALID);
-    dbus_g_proxy_connect_signal(scan_info->sig_proxy,
-            BTSEARCH_SEARCH_COMPLETE_SIG,
-            G_CALLBACK(scan_cb_search_complete), scan_info, NULL);
-
-    error = NULL;
-    if(!dbus_g_proxy_call(scan_info->req_proxy, BTSEARCH_START_SEARCH_REQ,
-                &error, G_TYPE_INVALID, G_TYPE_INVALID))
-    {
-        if(error->domain == DBUS_GERROR
-                && error->code == DBUS_GERROR_REMOTE_EXCEPTION)
-        {
-            g_printerr("Caught remote method exception %s: %s",
-                    dbus_g_error_get_name(error),
-                    error->message);
-        }
-        else
-            g_printerr("Error: %s\n", error->message);
-        return 3;
-    }
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-    return 0;
-}
-
-/**
- * Scan for all bluetooth devices.  This method can take a few seconds,
- * during which the UI will freeze.
- */
-static gboolean
-scan_bluetooth(GtkWidget *widget, ScanInfo *scan_info)
-{
-    GError *error = NULL;
-    GtkWidget *dialog = NULL;
-    GtkWidget *lst_devices = NULL;
-    GtkTreeViewColumn *column = NULL;
-    GtkCellRenderer *renderer = NULL;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    dialog = gtk_dialog_new_with_buttons(_("Select Bluetooth Device"),
-            GTK_WINDOW(scan_info->settings_dialog), GTK_DIALOG_MODAL,
-            GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
-            GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
-            NULL);
-
-    scan_info->scan_dialog = dialog;
-
-    scan_info->store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
-
-    gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 300);
-
-    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
-            lst_devices = gtk_tree_view_new_with_model(
-                GTK_TREE_MODEL(scan_info->store)), TRUE, TRUE, 0);
-
-    g_object_unref(G_OBJECT(scan_info->store));
-
-    gtk_tree_selection_set_mode(
-            gtk_tree_view_get_selection(GTK_TREE_VIEW(lst_devices)),
-            GTK_SELECTION_SINGLE);
-    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(lst_devices), TRUE);
-
-    renderer = gtk_cell_renderer_text_new();
-    column = gtk_tree_view_column_new_with_attributes(
-            _("MAC"), renderer, "text", 0, NULL);
-    gtk_tree_view_append_column(GTK_TREE_VIEW(lst_devices), column);
-
-    renderer = gtk_cell_renderer_text_new();
-    column = gtk_tree_view_column_new_with_attributes(
-            _("Description"), renderer, "text", 1, NULL);
-    gtk_tree_view_append_column(GTK_TREE_VIEW(lst_devices), column);
-
-    gtk_widget_show_all(dialog);
-
-    scan_info->banner = hildon_banner_show_animation(dialog, NULL,
-            _("Scanning for Bluetooth Devices"));
-
-    if(scan_start_search(scan_info))
-    {
-        gtk_widget_destroy(scan_info->banner);
-        popup_error(scan_info->settings_dialog,
-                _("An error occurred while attempting to scan for "
-                "bluetooth devices."));
-    }
-    else while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
-    {
-        GtkTreeIter iter;
-        if(gtk_tree_selection_get_selected(
-                    gtk_tree_view_get_selection(GTK_TREE_VIEW(lst_devices)),
-                    NULL, &iter))
-        {
-            gchar *mac;
-            gtk_tree_model_get(GTK_TREE_MODEL(scan_info->store),
-                    &iter, 0, &mac, -1);
-            gtk_entry_set_text(GTK_ENTRY(scan_info->txt_rcvr_mac), mac);
-            break;
-        }
-        else
-            popup_error(dialog,
-                    _("Please select a bluetooth device from the list."));
-    }
-
-    gtk_widget_destroy(dialog);
-
-    /* Clean up D-Bus. */
-    dbus_g_proxy_call(scan_info->req_proxy, BTSEARCH_STOP_SEARCH_REQ,
-                &error, G_TYPE_INVALID, G_TYPE_INVALID);
-    g_object_unref(scan_info->req_proxy);
-    g_object_unref(scan_info->sig_proxy);
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-typedef struct _BrowseInfo BrowseInfo;
-struct _BrowseInfo {
-    GtkWidget *dialog;
-    GtkWidget *txt;
-};
-
-static gboolean
-settings_dialog_browse_forfile(GtkWidget *widget, BrowseInfo *browse_info)
-{
-    GtkWidget *dialog;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    dialog = GTK_WIDGET(
-            hildon_file_chooser_dialog_new(GTK_WINDOW(browse_info->dialog),
-            GTK_FILE_CHOOSER_ACTION_OPEN));
-
-    gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(dialog), TRUE);
-    gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),
-            gtk_entry_get_text(GTK_ENTRY(browse_info->txt)));
-
-    if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(dialog)))
-    {
-        gchar *filename = gtk_file_chooser_get_filename(
-                GTK_FILE_CHOOSER(dialog));
-        gtk_entry_set_text(GTK_ENTRY(browse_info->txt), filename);
-        g_free(filename);
-    }
-
-    gtk_widget_destroy(dialog);
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-typedef struct _KeysDialogInfo KeysDialogInfo;
-struct _KeysDialogInfo {
-    GtkWidget *cmb[CUSTOM_KEY_ENUM_COUNT];
-};
-
-static gboolean
-settings_dialog_hardkeys_reset(GtkWidget *widget, KeysDialogInfo *cdi)
-{
-    GtkWidget *confirm;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    confirm = hildon_note_new_confirmation(GTK_WINDOW(_window),
-            _("Reset all hardware keys to their original defaults?"));
-
-    if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm)))
-    {
-        gint i;
-        for(i = 0; i < CUSTOM_KEY_ENUM_COUNT; i++)
-            gtk_combo_box_set_active(GTK_COMBO_BOX(cdi->cmb[i]),
-                    CUSTOM_KEY_DEFAULT[i]);
-    }
-    gtk_widget_destroy(confirm);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-settings_dialog_hardkeys(GtkWidget *widget, GtkWidget *parent)
-{
-    gint i;
-    static GtkWidget *dialog = NULL;
-    static GtkWidget *table = NULL;
-    static GtkWidget *label = NULL;
-    static KeysDialogInfo bdi;
-    static GtkWidget *btn_defaults = NULL;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(dialog == NULL)
-    {
-        dialog = gtk_dialog_new_with_buttons(_("Hardware Keys"),
-                GTK_WINDOW(parent), GTK_DIALOG_MODAL,
-                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
-                NULL);
-
-        gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
-                btn_defaults = gtk_button_new_with_label(_("Reset...")));
-        g_signal_connect(G_OBJECT(btn_defaults), "clicked",
-                          G_CALLBACK(settings_dialog_hardkeys_reset), &bdi);
-
-        gtk_dialog_add_button(GTK_DIALOG(dialog),
-                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
-
-        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
-                table = gtk_table_new(2, 9, FALSE), TRUE, TRUE, 0);
-        for(i = 0; i < CUSTOM_KEY_ENUM_COUNT; i++)
-        {
-            gint j;
-            gtk_table_attach(GTK_TABLE(table),
-                    label = gtk_label_new(""),
-                    0, 1, i, i + 1, GTK_FILL, 0, 2, 1);
-            gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-            gtk_label_set_markup(GTK_LABEL(label), CUSTOM_KEY_ICON[i]);
-            gtk_table_attach(GTK_TABLE(table),
-                    bdi.cmb[i] = gtk_combo_box_new_text(),
-                    1, 2, i, i + 1, GTK_FILL, 0, 2, 1);
-            for(j = 0; j < CUSTOM_ACTION_ENUM_COUNT; j++)
-                gtk_combo_box_append_text(GTK_COMBO_BOX(bdi.cmb[i]),
-                        CUSTOM_ACTION_TEXT[j]);
-        }
-    }
-
-    /* Initialize contents of the combo boxes. */
-    for(i = 0; i < CUSTOM_KEY_ENUM_COUNT; i++)
-        gtk_combo_box_set_active(GTK_COMBO_BOX(bdi.cmb[i]), _action[i]);
-
-    gtk_widget_show_all(dialog);
-
-OUTER_WHILE:
-    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
-    {
-        /* Check for duplicates. */
-        for(i = 0; i < CUSTOM_KEY_ENUM_COUNT; i++)
-        {
-            gint j;
-            for(j = i + 1; j < CUSTOM_KEY_ENUM_COUNT; j++)
-            {
-                if(gtk_combo_box_get_active(GTK_COMBO_BOX(bdi.cmb[i]))
-                        == gtk_combo_box_get_active(GTK_COMBO_BOX(bdi.cmb[j])))
-                {
-                    GtkWidget *confirm;
-                    gchar *buffer = g_strdup_printf("%s:\n    %s\n%s",
-                        _("The following action is mapped to multiple keys"),
-                        CUSTOM_ACTION_TEXT[gtk_combo_box_get_active(
-                            GTK_COMBO_BOX(bdi.cmb[i]))],
-                        _("Continue?"));
-                    confirm = hildon_note_new_confirmation(GTK_WINDOW(_window),
-                            buffer);
-
-                    if(GTK_RESPONSE_OK != gtk_dialog_run(GTK_DIALOG(confirm)))
-                    {
-                        gtk_widget_destroy(confirm);
-                        goto OUTER_WHILE;
-                    }
-                    gtk_widget_destroy(confirm);
-                }
-            }
-        }
-        for(i = 0; i < CUSTOM_KEY_ENUM_COUNT; i++)
-            _action[i] = gtk_combo_box_get_active(GTK_COMBO_BOX(bdi.cmb[i]));
-        break;
-    }
-
-    gtk_widget_hide(dialog);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-typedef struct _ColorsDialogInfo ColorsDialogInfo;
-struct _ColorsDialogInfo {
-    GtkWidget *col[COLORABLE_ENUM_COUNT];
-};
-
-static gboolean
-settings_dialog_colors_reset(GtkWidget *widget, ColorsDialogInfo *cdi)
-{
-    GtkWidget *confirm;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    confirm = hildon_note_new_confirmation(GTK_WINDOW(_window),
-            _("Reset all colors to their original defaults?"));
-
-    if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm)))
-    {
-        gint i;
-        for(i = 0; i < COLORABLE_ENUM_COUNT; i++)
-        {
-            hildon_color_button_set_color(
-                    HILDON_COLOR_BUTTON(cdi->col[i]),
-                    &COLORABLE_DEFAULT[i]);
-        }
-    }
-    gtk_widget_destroy(confirm);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-settings_dialog_colors(GtkWidget *widget, GtkWidget *parent)
-{
-    static GtkWidget *dialog = NULL;
-    static GtkWidget *table = NULL;
-    static GtkWidget *label = NULL;
-    static GtkWidget *btn_defaults = NULL;
-    static ColorsDialogInfo cdi;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(dialog == NULL)
-    {
-        dialog = gtk_dialog_new_with_buttons(_("Colors"),
-                GTK_WINDOW(parent), GTK_DIALOG_MODAL,
-                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
-                NULL);
-
-        gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
-                btn_defaults = gtk_button_new_with_label(_("Reset...")));
-        g_signal_connect(G_OBJECT(btn_defaults), "clicked",
-                          G_CALLBACK(settings_dialog_colors_reset), &cdi);
-
-        gtk_dialog_add_button(GTK_DIALOG(dialog),
-                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
-
-        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
-                table = gtk_table_new(4, 3, FALSE), TRUE, TRUE, 0);
-
-        /* GPS. */
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("GPS")),
-                0, 1, 0, 1, GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(table),
-                cdi.col[COLORABLE_MARK] = hildon_color_button_new(),
-                1, 2, 0, 1, 0, 0, 2, 4);
-        gtk_table_attach(GTK_TABLE(table),
-                cdi.col[COLORABLE_MARK_VELOCITY] = hildon_color_button_new(),
-                2, 3, 0, 1, 0, 0, 2, 4);
-        gtk_table_attach(GTK_TABLE(table),
-                cdi.col[COLORABLE_MARK_OLD] = hildon_color_button_new(),
-                3, 4, 0, 1, 0, 0, 2, 4);
-
-        /* Track. */
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("Track")),
-                0, 1, 1, 2, GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(table),
-                cdi.col[COLORABLE_TRACK] = hildon_color_button_new(),
-                1, 2, 1, 2, 0, 0, 2, 4);
-        gtk_table_attach(GTK_TABLE(table),
-                cdi.col[COLORABLE_TRACK_MARK] = hildon_color_button_new(),
-                2, 3, 1, 2, 0, 0, 2, 4);
-        gtk_table_attach(GTK_TABLE(table),
-                cdi.col[COLORABLE_TRACK_BREAK] = hildon_color_button_new(),
-                3, 4, 1, 2, 0, 0, 2, 4);
-
-        /* Route. */
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("Route")),
-                0, 1, 2, 3, GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(table),
-                cdi.col[COLORABLE_ROUTE] = hildon_color_button_new(),
-                1, 2, 2, 3, 0, 0, 2, 4);
-        gtk_table_attach(GTK_TABLE(table),
-                cdi.col[COLORABLE_ROUTE_WAY] = hildon_color_button_new(),
-                2, 3, 2, 3, 0, 0, 2, 4);
-        gtk_table_attach(GTK_TABLE(table),
-                cdi.col[COLORABLE_ROUTE_BREAK] = hildon_color_button_new(),
-                3, 4, 2, 3, 0, 0, 2, 4);
-
-        /* POI. */
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("POI")),
-                0, 1, 3, 4, GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(table),
-                cdi.col[COLORABLE_POI] = hildon_color_button_new(),
-                1, 2, 3, 4, 0, 0, 2, 4);
-    }
-
-    /* Initialize GPS. */
-    hildon_color_button_set_color(
-            HILDON_COLOR_BUTTON(cdi.col[COLORABLE_MARK]),
-            &_color[COLORABLE_MARK]);
-    hildon_color_button_set_color(
-            HILDON_COLOR_BUTTON(cdi.col[COLORABLE_MARK_VELOCITY]),
-            &_color[COLORABLE_MARK_VELOCITY]);
-    hildon_color_button_set_color(
-            HILDON_COLOR_BUTTON(cdi.col[COLORABLE_MARK_OLD]),
-            &_color[COLORABLE_MARK_OLD]);
-
-    /* Initialize Track. */
-    hildon_color_button_set_color(
-            HILDON_COLOR_BUTTON(cdi.col[COLORABLE_TRACK]),
-            &_color[COLORABLE_TRACK]);
-    hildon_color_button_set_color(
-            HILDON_COLOR_BUTTON(cdi.col[COLORABLE_TRACK_MARK]),
-            &_color[COLORABLE_TRACK_MARK]);
-    hildon_color_button_set_color(
-            HILDON_COLOR_BUTTON(cdi.col[COLORABLE_TRACK_BREAK]),
-            &_color[COLORABLE_TRACK_BREAK]);
-
-    /* Initialize Route. */
-    hildon_color_button_set_color(
-            HILDON_COLOR_BUTTON(cdi.col[COLORABLE_ROUTE]),
-            &_color[COLORABLE_ROUTE]);
-    hildon_color_button_set_color(
-            HILDON_COLOR_BUTTON(cdi.col[COLORABLE_ROUTE_WAY]),
-            &_color[COLORABLE_ROUTE_WAY]);
-    hildon_color_button_set_color(
-            HILDON_COLOR_BUTTON(cdi.col[COLORABLE_ROUTE_BREAK]),
-            &_color[COLORABLE_ROUTE_BREAK]);
-
-    /* Initialize POI. */
-    hildon_color_button_set_color(
-            HILDON_COLOR_BUTTON(cdi.col[COLORABLE_POI]),
-            &_color[COLORABLE_POI]);
-
-    gtk_widget_show_all(dialog);
-
-    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
-    {
-        GdkColor *color;
-
-        color = hildon_color_button_get_color(
-                HILDON_COLOR_BUTTON(cdi.col[COLORABLE_MARK]));
-        _color[COLORABLE_MARK] = *color;
-
-        color = hildon_color_button_get_color(
-                HILDON_COLOR_BUTTON(cdi.col[COLORABLE_MARK_VELOCITY]));
-        _color[COLORABLE_MARK_VELOCITY] = *color;
-
-        color = hildon_color_button_get_color(
-                HILDON_COLOR_BUTTON(cdi.col[COLORABLE_MARK_OLD]));
-        _color[COLORABLE_MARK_OLD] = *color;
-
-        color = hildon_color_button_get_color(
-                HILDON_COLOR_BUTTON(cdi.col[COLORABLE_TRACK]));
-        _color[COLORABLE_TRACK] = *color;
-
-        color = hildon_color_button_get_color(
-                HILDON_COLOR_BUTTON(cdi.col[COLORABLE_TRACK_MARK]));
-        _color[COLORABLE_TRACK_MARK] = *color;
-
-        color = hildon_color_button_get_color(
-                HILDON_COLOR_BUTTON(cdi.col[COLORABLE_TRACK_BREAK]));
-        _color[COLORABLE_TRACK_BREAK] = *color;
-
-        color = hildon_color_button_get_color(
-                HILDON_COLOR_BUTTON(cdi.col[COLORABLE_ROUTE]));
-        _color[COLORABLE_ROUTE] = *color;
-
-        color = hildon_color_button_get_color(
-                HILDON_COLOR_BUTTON(cdi.col[COLORABLE_ROUTE_WAY]));
-        _color[COLORABLE_ROUTE_WAY] = *color;
-
-        color = hildon_color_button_get_color(
-                HILDON_COLOR_BUTTON(cdi.col[COLORABLE_ROUTE_BREAK]));
-        _color[COLORABLE_ROUTE_BREAK] = *color;
-
-        color = hildon_color_button_get_color(
-                HILDON_COLOR_BUTTON(cdi.col[COLORABLE_POI]));
-        _color[COLORABLE_POI] = *color;
-
-        update_gcs();
-        break;
-    }
-
-    gtk_widget_hide(dialog);
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-/**
- * Bring up the Settings dialog.  Return TRUE if and only if the recever
- * information has changed (MAC or channel).
- */
-static gboolean
-settings_dialog()
-{
-    static GtkWidget *dialog = NULL;
-    static GtkWidget *notebook = NULL;
-    static GtkWidget *table = NULL;
-    static GtkWidget *hbox = NULL;
-    static GtkWidget *hbox2 = NULL;
-    static GtkWidget *label = NULL;
-    static GtkWidget *txt_rcvr_mac = NULL;
-    static GtkWidget *num_center_ratio = NULL;
-    static GtkWidget *num_lead_ratio = NULL;
-    static GtkWidget *num_announce_notice = NULL;
-    static GtkWidget *chk_enable_voice = NULL;
-    static GtkWidget *num_voice_speed = NULL;
-    static GtkWidget *num_voice_pitch = NULL;
-    static GtkWidget *lbl_voice_speed = NULL;
-    static GtkWidget *lbl_voice_pitch = NULL;
-    static GtkWidget *num_draw_width = NULL;
-    static GtkWidget *chk_always_keep_on = NULL;
-    static GtkWidget *cmb_units = NULL;
-    static GtkWidget *cmb_degformat = NULL;
-    static GtkWidget *btn_scan = NULL;
-    static GtkWidget *btn_buttons = NULL;
-    static GtkWidget *btn_colors = NULL;
-
-    static GtkWidget *txt_poi_db = NULL;
-    static GtkWidget *btn_browsepoi = NULL;
-    static GtkWidget *num_poi_zoom = NULL;
-    static GtkWidget *chk_speed_limit_on = NULL;
-    static GtkWidget *num_speed = NULL;
-    static GtkWidget *cmb_speed_location = NULL;
-    static GtkWidget *cmb_info_font_size = NULL;
-
-    static BrowseInfo browse_info = {0, 0};
-    static ScanInfo scan_info = {0};
-    gboolean rcvr_changed = FALSE;
-    guint i;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(dialog == NULL)
-    {
-        dialog = gtk_dialog_new_with_buttons(_("Settings"),
-                GTK_WINDOW(_window), GTK_DIALOG_MODAL,
-                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
-                NULL);
-
-        /* Enable the help button. */
-        ossohelp_dialog_help_enable(
-                GTK_DIALOG(dialog), HELP_ID_SETTINGS, _osso);
-
-        gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
-               btn_buttons = gtk_button_new_with_label(_("Hardware Keys...")));
-
-        gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
-                btn_colors = gtk_button_new_with_label(_("Colors...")));
-
-        gtk_dialog_add_button(GTK_DIALOG(dialog),
-                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
-
-        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
-                notebook = gtk_notebook_new(), TRUE, TRUE, 0);
-
-        /* Receiver page. */
-        gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
-                table = gtk_table_new(2, 3, FALSE),
-                label = gtk_label_new(_("GPS")));
-
-        /* Receiver MAC Address. */
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("MAC")),
-                0, 1, 0, 1, GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(table),
-                hbox = gtk_hbox_new(FALSE, 4),
-                1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-        gtk_box_pack_start(GTK_BOX(hbox),
-                txt_rcvr_mac = gtk_entry_new(),
-                TRUE, TRUE, 0);
-        gtk_box_pack_start(GTK_BOX(hbox),
-                btn_scan = gtk_button_new_with_label(_("Scan...")),
-                FALSE, FALSE, 0);
-
-        /* Note!. */
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(
-                    _("Note: You can enter a device path\n"
-                        "(e.g. \"/dev/rfcomm0\").")),
-                0, 2, 1, 2, GTK_FILL, 0, 2, 4);
-        gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
-        gtk_misc_set_alignment(GTK_MISC(label), 0.5f, 0.5f);
-
-
-        /* Auto-Center page. */
-        gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
-                table = gtk_table_new(2, 2, FALSE),
-                label = gtk_label_new(_("Auto-Center")));
-
-        /* Auto-Center Sensitivity. */
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("Sensitivity")),
-                0, 1, 0, 1, GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
-                1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-        gtk_container_add(GTK_CONTAINER(label),
-                num_center_ratio = hildon_controlbar_new());
-        hildon_controlbar_set_range(HILDON_CONTROLBAR(num_center_ratio), 1,10);
-        force_min_visible_bars(HILDON_CONTROLBAR(num_center_ratio), 1);
-
-        /* Lead Amount. */
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("Lead Amount")),
-                0, 1, 1, 2, GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
-                1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-        gtk_container_add(GTK_CONTAINER(label),
-                num_lead_ratio = hildon_controlbar_new());
-        hildon_controlbar_set_range(HILDON_CONTROLBAR(num_lead_ratio), 1, 10);
-        force_min_visible_bars(HILDON_CONTROLBAR(num_lead_ratio), 1);
-
-        /* Announcement. */
-        gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
-                table = gtk_table_new(2, 3, FALSE),
-                label = gtk_label_new(_("Announce")));
-
-        /* Announcement Advance Notice. */
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("Advance Notice")),
-                0, 1, 0, 1, GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(table),
-                num_announce_notice = hildon_controlbar_new(),
-                1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-        hildon_controlbar_set_range(
-                HILDON_CONTROLBAR(num_announce_notice), 1, 20);
-        force_min_visible_bars(HILDON_CONTROLBAR(num_announce_notice), 1);
-
-        /* Enable Voice. */
-        gtk_table_attach(GTK_TABLE(table),
-                chk_enable_voice = gtk_check_button_new_with_label(
-                    _("Enable Voice Synthesis (requires flite)")),
-                0, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chk_enable_voice),
-                _enable_voice);
-
-        /* Voice Speed and Pitch. */
-        gtk_table_attach(GTK_TABLE(table),
-                hbox = gtk_hbox_new(FALSE, 12),
-                0, 2, 2, 3, 0, 0, 2, 6);
-        gtk_box_pack_start(GTK_BOX(hbox),
-                hbox2 = gtk_hbox_new(FALSE, 4),
-                TRUE, TRUE, 4);
-        gtk_box_pack_start(GTK_BOX(hbox2),
-                lbl_voice_speed = gtk_label_new(_("Speed")),
-                TRUE, TRUE, 0);
-        gtk_box_pack_start(GTK_BOX(hbox2),
-                num_voice_speed = hildon_controlbar_new(),
-                TRUE, TRUE, 0);
-        hildon_controlbar_set_range(HILDON_CONTROLBAR(num_voice_speed), 1, 10);
-        force_min_visible_bars(HILDON_CONTROLBAR(num_voice_speed), 1);
-
-        gtk_box_pack_start(GTK_BOX(hbox),
-                hbox2 = gtk_hbox_new(FALSE, 4),
-                TRUE, TRUE, 4);
-        gtk_box_pack_start(GTK_BOX(hbox2),
-                lbl_voice_pitch = gtk_label_new(_("Pitch")),
-                TRUE, TRUE, 0);
-        gtk_box_pack_start(GTK_BOX(hbox2),
-                num_voice_pitch = hildon_controlbar_new(),
-                TRUE, TRUE, 0);
-        hildon_controlbar_set_range(HILDON_CONTROLBAR(num_voice_pitch), -2, 8);
-        force_min_visible_bars(HILDON_CONTROLBAR(num_voice_pitch), 1);
-
-        /* Misc. page. */
-        gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
-                table = gtk_table_new(2, 3, FALSE),
-                label = gtk_label_new(_("Misc.")));
-
-        /* Line Width. */
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("Line Width")),
-                0, 1, 0, 1, GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(table),
-                num_draw_width = hildon_controlbar_new(),
-                1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-        hildon_controlbar_set_range(HILDON_CONTROLBAR(num_draw_width), 1, 20);
-        force_min_visible_bars(HILDON_CONTROLBAR(num_draw_width), 1);
-
-        /* Keep Display On Only When Fullscreen. */
-        gtk_table_attach(GTK_TABLE(table),
-                chk_always_keep_on = gtk_check_button_new_with_label(
-                    _("Keep Display On Only in Fullscreen Mode")),
-                0, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-
-        /* Information Font Size. */
-        gtk_table_attach(GTK_TABLE(table),
-                hbox = gtk_hbox_new(FALSE, 4),
-                0, 2, 2, 3, GTK_FILL, 0, 2, 4);
-        gtk_box_pack_start(GTK_BOX(hbox),
-                label = gtk_label_new(_("Information Font Size")),
-                FALSE, FALSE, 0);
-        gtk_box_pack_start(GTK_BOX(hbox),
-                cmb_info_font_size = gtk_combo_box_new_text(),
-                FALSE, FALSE, 0);
-        for(i = 0; i < INFO_FONT_ENUM_COUNT; i++)
-            gtk_combo_box_append_text(GTK_COMBO_BOX(cmb_info_font_size),
-                    INFO_FONT_TEXT[i]);
-
-        /* Misc. 2 page. */
-        gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
-                table = gtk_table_new(2, 3, FALSE),
-                label = gtk_label_new(_("Misc. 2")));
-
-        /* Units. */
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("Units")),
-                0, 1, 0, 1, GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(table),
-                cmb_units = gtk_combo_box_new_text(),
-                1, 2, 0, 1, GTK_FILL, 0, 2, 4);
-        for(i = 0; i < UNITS_ENUM_COUNT; i++)
-            gtk_combo_box_append_text(GTK_COMBO_BOX(cmb_units), UNITS_TEXT[i]);
-
-        /* Degrees format */
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("Degrees Format")),
-                0, 1, 1, 2, GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
-                1, 2, 1, 2, GTK_FILL, 0, 2, 4);
-        gtk_container_add(GTK_CONTAINER(label),
-                cmb_degformat = gtk_combo_box_new_text());
-        for(i = 0; i < DEG_FORMAT_ENUM_COUNT; i++)
-            gtk_combo_box_append_text(GTK_COMBO_BOX(cmb_degformat),
-                DEG_FORMAT_TEXT[i]);
-
-        gtk_table_attach(GTK_TABLE(table),
-                gtk_label_new(""),
-                2, 3, 0, 2, GTK_FILL | GTK_EXPAND, 0, 2, 4);
-
-        /* Speed warner. */
-        gtk_table_attach(GTK_TABLE(table),
-                hbox = gtk_hbox_new(FALSE, 4),
-                0, 3, 2, 3, GTK_FILL, 0, 2, 4);
-
-        gtk_box_pack_start(GTK_BOX(hbox),
-                chk_speed_limit_on = gtk_check_button_new_with_label(
-                    _("Speed Limit")),
-                FALSE, FALSE, 0);
-
-        gtk_box_pack_start(GTK_BOX(hbox),
-                label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
-                FALSE, FALSE, 0);
-        gtk_container_add(GTK_CONTAINER(label),
-                num_speed = hildon_number_editor_new(0, 999));
-
-        gtk_box_pack_start(GTK_BOX(hbox),
-                label = gtk_label_new(_("Location")),
-                FALSE, FALSE, 0);
-        gtk_box_pack_start(GTK_BOX(hbox),
-                label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
-                FALSE, FALSE, 0);
-        gtk_container_add(GTK_CONTAINER(label),
-                cmb_speed_location = gtk_combo_box_new_text());
-        for(i = 0; i < SPEED_LOCATION_ENUM_COUNT; i++)
-            gtk_combo_box_append_text(GTK_COMBO_BOX(cmb_speed_location),
-                    SPEED_LOCATION_TEXT[i]);
-
-
-        /* POI page */
-        gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
-                table = gtk_table_new(2, 3, FALSE),
-                label = gtk_label_new(_("POI")));
-
-        /* POI database. */
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("POI database")),
-                0, 1, 1, 2, GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(table),
-                hbox = gtk_hbox_new(FALSE, 4),
-                1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-        gtk_box_pack_start(GTK_BOX(hbox),
-                txt_poi_db = gtk_entry_new(),
-                TRUE, TRUE, 0);
-        gtk_box_pack_start(GTK_BOX(hbox),
-                btn_browsepoi = gtk_button_new_with_label(_("Browse...")),
-                FALSE, FALSE, 0);
-
-        /* Show POI below zoom. */
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("Show POI below zoom")),
-                0, 1, 2, 3, GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
-                1, 2, 2, 3, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-        gtk_container_add(GTK_CONTAINER(label),
-                num_poi_zoom = hildon_number_editor_new(0, MAX_ZOOM));
-
-        /* Connect signals. */
-        scan_info.settings_dialog = dialog;
-        scan_info.txt_rcvr_mac = txt_rcvr_mac;
-        g_signal_connect(G_OBJECT(btn_scan), "clicked",
-                         G_CALLBACK(scan_bluetooth), &scan_info);
-        g_signal_connect(G_OBJECT(btn_buttons), "clicked",
-                         G_CALLBACK(settings_dialog_hardkeys), dialog);
-        g_signal_connect(G_OBJECT(btn_colors), "clicked",
-                         G_CALLBACK(settings_dialog_colors), dialog);
-
-        browse_info.dialog = dialog;
-        browse_info.txt = txt_poi_db;
-        g_signal_connect(G_OBJECT(btn_browsepoi), "clicked",
-                G_CALLBACK(settings_dialog_browse_forfile), &browse_info);
-    }
-
-
-    /* Initialize fields. */
-    if(_rcvr_mac)
-        gtk_entry_set_text(GTK_ENTRY(txt_rcvr_mac), _rcvr_mac);
-    if(_poi_db)
-        gtk_entry_set_text(GTK_ENTRY(txt_poi_db), _poi_db);
-    hildon_number_editor_set_value(HILDON_NUMBER_EDITOR(num_poi_zoom),
-            _poi_zoom);
-    hildon_controlbar_set_value(HILDON_CONTROLBAR(num_center_ratio),
-            _center_ratio);
-    hildon_controlbar_set_value(HILDON_CONTROLBAR(num_lead_ratio),
-            _lead_ratio);
-    hildon_controlbar_set_value(HILDON_CONTROLBAR(num_announce_notice),
-            _announce_notice_ratio);
-    hildon_controlbar_set_value(HILDON_CONTROLBAR(num_voice_speed),
-            (gint)(_voice_speed * 3 + 0.5));
-    hildon_controlbar_set_value(HILDON_CONTROLBAR(num_voice_pitch),
-            _voice_pitch);
-    hildon_controlbar_set_value(HILDON_CONTROLBAR(num_draw_width),
-            _draw_width);
-    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chk_always_keep_on),
-            !_always_keep_on);
-    gtk_combo_box_set_active(GTK_COMBO_BOX(cmb_units), _units);
-    gtk_combo_box_set_active(GTK_COMBO_BOX(cmb_degformat), _degformat);
-    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chk_speed_limit_on),
-            _speed_limit_on);
-    hildon_number_editor_set_range(HILDON_NUMBER_EDITOR(num_speed),
-            1, 300);
-    hildon_number_editor_set_value(HILDON_NUMBER_EDITOR(num_speed),
-            _speed_limit);
-    gtk_combo_box_set_active(GTK_COMBO_BOX(cmb_speed_location),
-            _speed_location);
-    gtk_combo_box_set_active(GTK_COMBO_BOX(cmb_info_font_size),
-            _info_font_size);
-
-    gtk_widget_show_all(dialog);
-
-    /* TODO: Uncomment the following hide function calls if moimart ever
-     * releases his dbus-based flite software. */
-    gtk_widget_hide(lbl_voice_speed);
-    gtk_widget_hide(num_voice_speed);
-    gtk_widget_hide(lbl_voice_pitch);
-    gtk_widget_hide(num_voice_pitch);
-
-    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
-    {
-        /* Set _rcvr_mac if necessary. */
-        if(!*gtk_entry_get_text(GTK_ENTRY(txt_rcvr_mac)))
-        {
-            /* User specified no rcvr mac - set _rcvr_mac to NULL. */
-            if(_rcvr_mac)
-            {
-                g_free(_rcvr_mac);
-                _rcvr_mac = NULL;
-                rcvr_changed = TRUE;
-                gtk_widget_set_sensitive(
-                        GTK_WIDGET(_menu_gps_details_item), FALSE);
-            }
-            if(_enable_gps)
-            {
-                gtk_check_menu_item_set_active(
-                        GTK_CHECK_MENU_ITEM(_menu_enable_gps_item), FALSE);
-                popup_error(dialog, _("No GPS Receiver MAC provided.\n"
-                        "GPS will be disabled."));
-                rcvr_changed = TRUE;
-                gtk_widget_set_sensitive(GTK_WIDGET(_menu_gps_details_item),
-                        FALSE);
-                gtk_widget_set_sensitive(GTK_WIDGET(_menu_gps_reset_item),
-                        FALSE);
-            }
-        }
-        else if(!_rcvr_mac || strcmp(_rcvr_mac,
-                      gtk_entry_get_text(GTK_ENTRY(txt_rcvr_mac))))
-        {
-            /* User specified a new rcvr mac. */
-            g_free(_rcvr_mac);
-            _rcvr_mac = g_strdup(gtk_entry_get_text(GTK_ENTRY(txt_rcvr_mac)));
-            rcvr_changed = TRUE;
-        }
-
-        _center_ratio = hildon_controlbar_get_value(
-                HILDON_CONTROLBAR(num_center_ratio));
-
-        _lead_ratio = hildon_controlbar_get_value(
-                HILDON_CONTROLBAR(num_lead_ratio));
-
-        _draw_width = hildon_controlbar_get_value(
-                HILDON_CONTROLBAR(num_draw_width));
-
-        _always_keep_on = !gtk_toggle_button_get_active(
-                GTK_TOGGLE_BUTTON(chk_always_keep_on));
-
-        _units = gtk_combo_box_get_active(GTK_COMBO_BOX(cmb_units));
-        _degformat = gtk_combo_box_get_active(GTK_COMBO_BOX(cmb_degformat));
-
-        _speed_limit_on = gtk_toggle_button_get_active(
-                GTK_TOGGLE_BUTTON(chk_speed_limit_on));
-        _speed_limit = hildon_number_editor_get_value(
-                HILDON_NUMBER_EDITOR(num_speed));
-        _speed_location = gtk_combo_box_get_active(
-                GTK_COMBO_BOX(cmb_speed_location));
-
-        _info_font_size = gtk_combo_box_get_active(
-                GTK_COMBO_BOX(cmb_info_font_size));
-
-        _announce_notice_ratio = hildon_controlbar_get_value(
-                HILDON_CONTROLBAR(num_announce_notice));
-
-        _voice_speed = hildon_controlbar_get_value(
-                HILDON_CONTROLBAR(num_voice_speed)) / 3.0;
-
-        _voice_pitch = hildon_controlbar_get_value(
-                HILDON_CONTROLBAR(num_voice_pitch));
-
-        _enable_voice = gtk_toggle_button_get_active(
-                GTK_TOGGLE_BUTTON(chk_enable_voice));
-
-        if(_db)
-        {
-            sqlite3_close(_db);
-            _db = NULL;
-        }
-        g_free(_poi_db);
-        if(strlen(gtk_entry_get_text(GTK_ENTRY(txt_poi_db))))
-        {
-            _poi_db = g_strdup(gtk_entry_get_text(GTK_ENTRY(txt_poi_db)));
-            db_connect();
-        }
-        else
-            _poi_db = NULL;
-
-        /* Sensitize menus based on whether we have a POI database conn. */
-        gtk_widget_set_sensitive(_cmenu_loc_add_poi, _db != NULL);
-        gtk_widget_set_sensitive(_cmenu_way_add_poi, _db != NULL);
-        gtk_widget_set_sensitive(_cmenu_poi, _db != NULL);
-        gtk_widget_set_sensitive(_menu_poi_item, _db != NULL);
-
-        _poi_zoom = hildon_number_editor_get_value(
-        HILDON_NUMBER_EDITOR(num_poi_zoom));
-
-        update_gcs();
-
-        config_save();
-        break;
-    }
-
-    gtk_widget_hide(dialog);
-
-    vprintf("%s(): return %d\n", __PRETTY_FUNCTION__, rcvr_changed);
-    return rcvr_changed;
-}
-
-static gint
-download_comparefunc(const ProgressUpdateInfo *a,
-        const ProgressUpdateInfo *b, gpointer user_data)
-{
-    gint diff = (a->priority - b->priority);
-    if(diff)
-        return diff;
-    diff = (a->tilex - b->tilex);
-    if(diff)
-        return diff;
-    diff = (a->tiley - b->tiley);
-    if(diff)
-        return diff;
-    diff = (a->zoom - b->zoom);
-    if(diff)
-        return diff;
-    diff = (a->repo - b->repo);
-    if(diff)
-        return diff;
-    /* Otherwise, deletes are "greatest" (least priority). */
-    if(!a->retries)
-        return (b->retries ? -1 : 0);
-    else if(!b->retries)
-        return (a->retries ? 1 : 0);
-    /* Do updates after non-updates (because they'll both be done anyway). */
-    return (a->retries - b->retries);
-}
-
-/**
- * Free a ProgressUpdateInfo data structure that was allocated during the
- * auto-map-download process.
- */
-static void
-progress_update_info_free(ProgressUpdateInfo *pui)
-{
-    vprintf("%s()\n", __PRETTY_FUNCTION__);
-
-    g_free(pui->src_str);
-    g_free(pui->dest_str);
-
-    g_slice_free(ProgressUpdateInfo, pui);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static void
-config_update_proxy()
-{
-    GConfClient *gconf_client = gconf_client_get_default();
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(_iap_http_proxy_host)
-        g_free(_iap_http_proxy_host);
-
-    /* Get proxy data and register for updates. */
-    if(gconf_client_get_bool(gconf_client,
-                GCONF_KEY_HTTP_PROXY_ON, NULL))
-    {
-        /* HTTP Proxy is on. */
-        _iap_http_proxy_host = gconf_client_get_string(gconf_client,
-                GCONF_KEY_HTTP_PROXY_HOST, NULL);
-        _iap_http_proxy_port = gconf_client_get_int(gconf_client,
-                GCONF_KEY_HTTP_PROXY_PORT, NULL);
-    }
-    else
-    {
-        /* HTTP Proxy is off. */
-        _iap_http_proxy_host = NULL;
-        _iap_http_proxy_port = 0;
-    }
-    g_object_unref(gconf_client);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static void
-set_repo_type(RepoData *repo)
-{
-    printf("%s(%s)\n", __PRETTY_FUNCTION__, repo->url);
-
-    if(repo->url && *repo->url)
-    {
-        gchar *url = g_utf8_strdown(repo->url, -1);
-
-        /* Determine type of repository. */
-        if(strstr(url, "service=wms"))
-            repo->type = REPOTYPE_WMS;
-        else if(strstr(url, "%s"))
-            repo->type = REPOTYPE_QUAD_QRST;
-        else if(strstr(url, "%0d"))
-            repo->type = REPOTYPE_XYZ_INV;
-        else if(strstr(url, "%0s"))
-            repo->type = REPOTYPE_QUAD_ZERO;
-        else
-            repo->type = REPOTYPE_XYZ;
-
-        g_free(url);
-    }
-    else
-        repo->type = REPOTYPE_NONE;
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static RepoData*
-config_parse_repo(gchar *str)
-{
-    /* Parse each part of a repo, delimited by newline characters:
-     * 1. name
-     * 2. url
-     * 3. cache_dir
-     * 4. dl_zoom_steps
-     * 5. view_zoom_steps
-     */
-    gchar *token, *error_check;
-    printf("%s(%s)\n", __PRETTY_FUNCTION__, str);
-
-    RepoData *rd = g_new0(RepoData, 1);
-
-    /* Parse name. */
-    token = strsep(&str, "\n\t");
-    if(token)
-        rd->name = g_strdup(token);
-
-    /* Parse URL format. */
-    token = strsep(&str, "\n\t");
-    if(token)
-        rd->url = g_strdup(token);
-
-    /* Parse cache dir. */
-    token = strsep(&str, "\n\t");
-    if(token)
-        rd->cache_dir = gnome_vfs_expand_initial_tilde(token);
-
-    /* Parse download zoom steps. */
-    token = strsep(&str, "\n\t");
-    if(!token || !*token || !(rd->dl_zoom_steps = atoi(token)))
-        rd->dl_zoom_steps = 2;
-
-    /* Parse view zoom steps. */
-    token = strsep(&str, "\n\t");
-    if(!token || !*token || !(rd->view_zoom_steps = atoi(token)))
-        rd->view_zoom_steps = 1;
-
-    /* Parse double-size. */
-    token = strsep(&str, "\n\t");
-    if(token)
-        rd->double_size = atoi(token); /* Default is zero (FALSE) */
-
-    /* Parse next-able. */
-    token = strsep(&str, "\n\t");
-    if(!token || !*token
-            || (rd->nextable = strtol(token, &error_check, 10), token == str))
-        rd->nextable = TRUE;
-
-    set_repo_type(rd);
-
-    vprintf("%s(): return %p\n", __PRETTY_FUNCTION__, rd);
-    return rd;
-}
-
-static gboolean
-repo_make_cache_dir(gchar *name, const gchar *cache_dir, GtkWidget *parent)
-{
-    printf("%s(%s)\n", __PRETTY_FUNCTION__, cache_dir);
-    if(g_mkdir_with_parents(cache_dir, 0755))
-    {
-        /* Failed to create Map Cache directory. */
-        gchar buffer[BUFFER_SIZE];
-        snprintf(buffer, sizeof(buffer), "%s: %s",
-                _("Unable to create cache directory for repository"),
-                name);
-        popup_error(parent, buffer);
-        vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
-        return FALSE;
-    }
-    vprintf("%s(): return %d\n", __PRETTY_FUNCTION__,
-            g_file_test(cache_dir, G_FILE_TEST_EXISTS));
-    return g_file_test(cache_dir, G_FILE_TEST_EXISTS);
-}
-
-static gboolean
-repo_set_curr(RepoData *rd)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-    _curr_repo = rd;
-    return repo_make_cache_dir(rd->name, rd->cache_dir, _window);
-}
-
-/**
- * Initialize all configuration from GCONF.  This should not be called more
- * than once during execution.
- */
-static void
-config_init()
-{
-    GConfValue *value;
-    GConfClient *gconf_client = gconf_client_get_default();
-    gchar *config_dir;
-    gchar *str;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(!gconf_client)
-    {
-        popup_error(_window, _("Failed to initialize GConf.  Quitting."));
-        exit(1);
-    }
-
-    /* Initialize config_dir. */
-    config_dir = gnome_vfs_expand_initial_tilde(CONFIG_DIR_NAME);
-    g_mkdir_with_parents(config_dir, 0700);
-
-    /* Retrieve route. */
-    {
-        gchar *route_file;
-        gchar *bytes;
-        gint size;
-
-        route_file = gnome_vfs_uri_make_full_from_relative(
-                config_dir, CONFIG_FILE_ROUTE);
-        if(GNOME_VFS_OK == gnome_vfs_read_entire_file(
-                    route_file, &size, &bytes))
-            parse_gpx(&_route, bytes, size, 0); /* 0 to replace route. */
-        g_free(route_file);
-    }
-
-    /* Retrieve track. */
-    {
-        gchar *track_file;
-        gchar *bytes;
-        gint size;
-
-        track_file = gnome_vfs_uri_make_full_from_relative(
-                config_dir, CONFIG_FILE_TRACK);
-        if(GNOME_VFS_OK == gnome_vfs_read_entire_file(
-                    track_file, &size, &bytes))
-            parse_gpx(&_track, bytes, size, 0); /* 0 to replace track. */
-        g_free(track_file);
-    }
-
-    /* Get Receiver MAC from GConf.  Default is scanned via hci_inquiry. */
-    {
-        _rcvr_mac = gconf_client_get_string(
-                gconf_client, GCONF_KEY_RCVR_MAC, NULL);
-    }
-
-    /* Get Auto-Download.  Default is FALSE. */
-    _auto_download = gconf_client_get_bool(gconf_client,
-            GCONF_KEY_AUTO_DOWNLOAD, NULL);
-
-    /* Get Center Ratio - Default is 3. */
-    _center_ratio = gconf_client_get_int(gconf_client,
-            GCONF_KEY_CENTER_SENSITIVITY, NULL);
-    if(!_center_ratio)
-        _center_ratio = 7;
-
-    /* Get Lead Ratio - Default is 5. */
-    _lead_ratio = gconf_client_get_int(gconf_client,
-            GCONF_KEY_LEAD_AMOUNT, NULL);
-    if(!_lead_ratio)
-        _lead_ratio = 5;
-
-    /* Get Draw Line Width- Default is 5. */
-    _draw_width = gconf_client_get_int(gconf_client,
-            GCONF_KEY_DRAW_WIDTH, NULL);
-    if(!_draw_width)
-        _draw_width = 5;
-
-    /* Get Announce Advance Notice - Default is 30. */
-    value = gconf_client_get(gconf_client, GCONF_KEY_ANNOUNCE_NOTICE, NULL);
-    if(value)
-    {
-        _announce_notice_ratio = gconf_value_get_int(value);
-        gconf_value_free(value);
-    }
-    else
-        _announce_notice_ratio = 8;
-
-    /* Get Enable Voice flag.  Default is TRUE. */
-    value = gconf_client_get(gconf_client, GCONF_KEY_ENABLE_VOICE, NULL);
-    if(value)
-    {
-        _enable_voice = gconf_value_get_bool(value);
-        gconf_value_free(value);
-    }
-    else
-        _enable_voice = TRUE;
-
-    /* Get Voice Speed - Default is 1.0. */
-    value = gconf_client_get(gconf_client, GCONF_KEY_VOICE_SPEED, NULL);
-    if(value)
-    {
-        _voice_speed = gconf_value_get_float(value);
-        gconf_value_free(value);
-    }
-    else
-        _voice_speed = 1.0;
-
-    /* Get Voice Speed - Default is 0. */
-    value = gconf_client_get(gconf_client, GCONF_KEY_VOICE_PITCH, NULL);
-    if(value)
-    {
-        _voice_pitch = gconf_value_get_int(value);
-        gconf_value_free(value);
-    }
-    else
-        _voice_pitch = 3;
-
-    /* Get Fullscreen flag. Default is FALSE. */
-    _fullscreen = gconf_client_get_bool(gconf_client,
-            GCONF_KEY_FULLSCREEN, NULL);
-
-    /* Get Always Keep On flag.  Default is FALSE. */
-    _always_keep_on = gconf_client_get_bool(gconf_client,
-            GCONF_KEY_ALWAYS_KEEP_ON, NULL);
-
-    /* Get Units.  Default is UNITS_KM. */
-    {
-        gchar *units_str = gconf_client_get_string(gconf_client,
-                GCONF_KEY_UNITS, NULL);
-        guint i = 0;
-        if(units_str)
-            for(i = UNITS_ENUM_COUNT - 1; i > 0; i--)
-                if(!strcmp(units_str, UNITS_TEXT[i]))
-                    break;
-        _units = i;
-    }
-
-    /* Get Custom Key Actions. */
-    {
-        gint i;
-        for(i = 0; i < CUSTOM_KEY_ENUM_COUNT; i++)
-        {
-            gint j = CUSTOM_KEY_DEFAULT[i];
-            gchar *str = gconf_client_get_string(gconf_client,
-                    CUSTOM_KEY_GCONF[i], NULL);
-            if(str)
-                for(j = CUSTOM_ACTION_ENUM_COUNT - 1; j > 0; j--)
-                    if(!strcmp(str, CUSTOM_ACTION_TEXT[j]))
-                        break;
-            _action[i] = j;
-        }
-    }
-
-    /* Get Deg format.  Default is DDPDDDDD. */
-    {
-        gchar *degformat_key_str = gconf_client_get_string(gconf_client,
-                GCONF_KEY_DEG_FORMAT, NULL);
-        guint i = 0;
-        if(degformat_key_str)
-            for(i = DEG_FORMAT_ENUM_COUNT - 1; i > 0; i--)
-                if(!strcmp(degformat_key_str, DEG_FORMAT_TEXT[i]))
-                    break;
-        _degformat = i;
-    }
-
-    /* Get Speed Limit On flag.  Default is FALSE. */
-    _speed_limit_on = gconf_client_get_bool(gconf_client,
-            GCONF_KEY_SPEED_LIMIT_ON, NULL);
-
-    /* Get Speed Limit */
-    _speed_limit = gconf_client_get_int(gconf_client,
-            GCONF_KEY_SPEED_LIMIT, NULL);
-    if(_speed_limit <= 0)
-        _speed_limit = 100;
-
-    /* Get Speed Location.  Default is SPEED_LOCATION_TOP_LEFT. */
-    {
-        gchar *speed_location_str = gconf_client_get_string(gconf_client,
-                GCONF_KEY_SPEED_LOCATION, NULL);
-        guint i = 0;
-        if(speed_location_str)
-            for(i = SPEED_LOCATION_ENUM_COUNT - 1; i > 0; i--)
-                if(!strcmp(speed_location_str, SPEED_LOCATION_TEXT[i]))
-                    break;
-        _speed_location = i;
-    }
-
-    /* Get Info Font Size.  Default is INFO_FONT_MEDIUM. */
-    {
-        gchar *info_font_size_str = gconf_client_get_string(gconf_client,
-                GCONF_KEY_INFO_FONT_SIZE, NULL);
-        guint i = -1;
-        if(info_font_size_str)
-            for(i = INFO_FONT_ENUM_COUNT - 1; i >= 0; i--)
-                if(!strcmp(info_font_size_str, INFO_FONT_TEXT[i]))
-                    break;
-        if(i == -1)
-            i = INFO_FONT_MEDIUM;
-        _info_font_size = i;
-    }
-
-    /* Get last saved latitude.  Default is 50.f. */
-    value = gconf_client_get(gconf_client, GCONF_KEY_LAT, NULL);
-    if(value)
-    {
-        _gps.lat = gconf_value_get_float(value);
-        gconf_value_free(value);
-    }
-    else
-        _gps.lat = 50.f;
-
-    /* Get last saved longitude.  Default is 0. */
-    value = gconf_client_get(gconf_client, GCONF_KEY_LON, NULL);
-    _gps.lon = gconf_client_get_float(gconf_client, GCONF_KEY_LON, NULL);
-
-    /* Get last center point. */
-    {
-        gfloat center_lat, center_lon;
-
-        /* Get last saved latitude.  Default is last saved latitude. */
-        value = gconf_client_get(gconf_client, GCONF_KEY_CENTER_LAT, NULL);
-        if(value)
-        {
-            center_lat = gconf_value_get_float(value);
-            gconf_value_free(value);
-        }
-        else
-            center_lat = _gps.lat;
-
-        /* Get last saved longitude.  Default is last saved longitude. */
-        value = gconf_client_get(gconf_client, GCONF_KEY_CENTER_LON, NULL);
-        if(value)
-        {
-            center_lon = gconf_value_get_float(value);
-            gconf_value_free(value);
-        }
-        else
-            center_lon = _gps.lon;
-
-        latlon2unit(center_lat, center_lon, _center.unitx, _center.unity);
-    }
-
-
-    /* Load the repositories. */
-    {
-        GSList *list, *curr;
-        guint curr_repo_index = gconf_client_get_int(gconf_client,
-            GCONF_KEY_CURRREPO, NULL);
-        list = gconf_client_get_list(gconf_client,
-            GCONF_KEY_REPOSITORIES, GCONF_VALUE_STRING, NULL);
-
-        for(curr = list; curr != NULL; curr = curr->next)
-        {
-            RepoData *rd = config_parse_repo(curr->data);
-            _repo_list = g_list_append(_repo_list, rd);
-            if(!curr_repo_index--)
-                repo_set_curr(rd);
-            g_free(curr->data);
-        }
-        g_slist_free(list);
-    }
-
-
-    if(_repo_list == NULL)
-    {
-        /* We have no repositories - create a default one. */
-        RepoData *repo = g_new(RepoData, 1);
-
-        /* Many fields can be retrieved from the "old" gconf keys. */
-
-        /* Get Map Cache Dir.  Default is REPO_DEFAULT_CACHE_DIR. */
-        repo->cache_dir = gconf_client_get_string(gconf_client,
-                GCONF_KEY_MAP_DIR_NAME, NULL);
-        if(!repo->cache_dir)
-            repo->cache_dir = gnome_vfs_expand_initial_tilde(
-                    REPO_DEFAULT_CACHE_DIR);
-
-        /* Get Map Download URL Format.  Default is "". */
-        repo->url = gconf_client_get_string(gconf_client,
-                GCONF_KEY_MAP_URI_FORMAT, NULL);
-        if(!repo->url)
-            repo->url=g_strdup(REPO_DEFAULT_MAP_URI);
-
-        /* Get Map Download Zoom Steps.  Default is 2. */
-        repo->dl_zoom_steps = gconf_client_get_int(gconf_client,
-                GCONF_KEY_MAP_ZOOM_STEPS, NULL);
-        if(!repo->dl_zoom_steps)
-            repo->dl_zoom_steps = REPO_DEFAULT_DL_ZOOM_STEPS;
-
-        /* Other fields are brand new. */
-        repo->name = g_strdup(REPO_DEFAULT_NAME);
-        repo->view_zoom_steps = REPO_DEFAULT_VIEW_ZOOM_STEPS;
-        repo->double_size = FALSE;
-        repo->nextable = TRUE;
-        set_repo_type(repo);
-
-        _repo_list = g_list_append(_repo_list, repo);
-        repo_set_curr(repo);
-    }
-
-    /* Get last Zoom Level.  Default is 12. */
-    value = gconf_client_get(gconf_client, GCONF_KEY_ZOOM, NULL);
-    if(value)
-    {
-        _zoom = gconf_value_get_int(value) / _curr_repo->view_zoom_steps
-            * _curr_repo->view_zoom_steps;
-        gconf_value_free(value);
-    }
-    else
-        _zoom = 12 / _curr_repo->view_zoom_steps
-            * _curr_repo->view_zoom_steps;
-    BOUND(_zoom, 0, MAX_ZOOM - 1);
-    _world_size_tiles = unit2tile(WORLD_SIZE_UNITS);
-
-    /* Speed and Heading are always initialized as 0. */
-    _gps.speed = 0.f;
-    _gps.heading = 0.f;
-
-    /* Get Route Directory.  Default is NULL. */
-    _route_dir_uri = gconf_client_get_string(gconf_client,
-            GCONF_KEY_ROUTEDIR, NULL);
-
-    /* Get Last Track File.  Default is NULL. */
-    _track_file_uri = gconf_client_get_string(gconf_client,
-            GCONF_KEY_TRACKFILE, NULL);
-
-    /* Get Auto-Center Mode.  Default is CENTER_LEAD. */
-    value = gconf_client_get(gconf_client, GCONF_KEY_AUTOCENTER_MODE, NULL);
-    if(value)
-    {
-        _center_mode = gconf_value_get_int(value);
-        gconf_value_free(value);
-    }
-    else
-        _center_mode = CENTER_LEAD;
-
-    /* Get Show Zoom Level flag.  Default is FALSE. */
-    _show_zoomlevel = gconf_client_get_bool(gconf_client,
-            GCONF_KEY_SHOWZOOMLEVEL, NULL);
-
-    /* Get Show Scale flag.  Default is TRUE. */
-    value = gconf_client_get(gconf_client, GCONF_KEY_SHOWSCALE, NULL);
-    if(value)
-    {
-        _show_scale = gconf_value_get_bool(value);
-        gconf_value_free(value);
-    }
-    else
-        _show_scale = TRUE;
-
-    /* Get Show Tracks flag.  Default is TRUE. */
-    value = gconf_client_get(gconf_client, GCONF_KEY_SHOWTRACKS, NULL);
-    if(value)
-    {
-        _show_tracks |= (gconf_value_get_bool(value) ? TRACKS_MASK : 0);
-        gconf_value_free(value);
-    }
-    else
-        _show_tracks |= TRACKS_MASK;
-
-    /* Get Show Routes flag.  Default is TRUE. */
-    value = gconf_client_get(gconf_client, GCONF_KEY_SHOWROUTES, NULL);
-    if(value)
-    {
-        _show_tracks |= (gconf_value_get_bool(value) ? ROUTES_MASK : 0);
-        gconf_value_free(value);
-    }
-    else
-        _show_tracks |= ROUTES_MASK;
-
-    /* Get Show Velocity Vector flag.  Default is TRUE. */
-    value = gconf_client_get(gconf_client, GCONF_KEY_SHOWVELVEC, NULL);
-    if(value)
-    {
-        _show_velvec = gconf_value_get_bool(value);
-        gconf_value_free(value);
-    }
-    else
-        _show_velvec = TRUE;
-
-    /* Get Show Velocity Vector flag.  Default is TRUE. */
-    value = gconf_client_get(gconf_client, GCONF_KEY_SHOWPOIS, NULL);
-    if(value)
-    {
-        _show_poi = gconf_value_get_bool(value);
-        gconf_value_free(value);
-    }
-    else
-        _show_poi = TRUE;
-
-    /* Get Enable GPS flag.  Default is TRUE. */
-    value = gconf_client_get(gconf_client, GCONF_KEY_ENABLE_GPS, NULL);
-    if(value)
-    {
-        _enable_gps = gconf_value_get_bool(value);
-        gconf_value_free(value);
-    }
-    else
-        _enable_gps = TRUE;
-
-    /* Initialize _conn_state based on _enable_gps. */
-    _conn_state = (_enable_gps ? RCVR_DOWN : RCVR_OFF);
-
-    /* Load the route locations. */
-    {
-        GSList *curr;
-        _loc_list = gconf_client_get_list(gconf_client,
-            GCONF_KEY_ROUTE_LOCATIONS, GCONF_VALUE_STRING, NULL);
-        _loc_model = gtk_list_store_new(1, G_TYPE_STRING);
-        for(curr = _loc_list; curr != NULL; curr = curr->next)
-        {
-            GtkTreeIter iter;
-            gtk_list_store_insert_with_values(_loc_model, &iter, INT_MAX,
-                    0, curr->data, -1);
-        }
-    }
-
-    /* Get POI Database.  Default is in REPO_DEFAULT_CACHE_BASE */
-    _poi_db = gconf_client_get_string(gconf_client,
-            GCONF_KEY_POI_DB, NULL);
-    if(_poi_db == NULL)
-    {
-        gchar *poi_base = gnome_vfs_expand_initial_tilde(
-                REPO_DEFAULT_CACHE_BASE);
-        _poi_db = gnome_vfs_uri_make_full_from_relative(
-                poi_base, "poi.db");
-        g_free(poi_base);
-    }
-    db_connect();
-
-    _poi_zoom = gconf_client_get_int(gconf_client,
-            GCONF_KEY_POI_ZOOM, NULL);
-    if(!_poi_zoom)
-    _poi_zoom = 6;
-
-
-    /* Get GPS Info flag.  Default is FALSE. */
-    _gps_info = gconf_client_get_bool(gconf_client, GCONF_KEY_GPS_INFO, NULL);
-
-    /* Get Route Download URL.  Default is:
-     * "http://www.gnuite.com/cgi-bin/gpx.cgi?saddr=%s&daddr=%s" */
-    _route_dl_url = gconf_client_get_string(gconf_client,
-            GCONF_KEY_ROUTE_DL_URL, NULL);
-    if(_route_dl_url == NULL)
-        _route_dl_url = g_strdup(
-                "http://www.gnuite.com/cgi-bin/gpx.cgi?saddr=%s&daddr=%s");
-
-    /* Get Route Download Radius.  Default is 4. */
-    value = gconf_client_get(gconf_client, GCONF_KEY_ROUTE_DL_RADIUS, NULL);
-    if(value)
-    {
-        _route_dl_radius = gconf_value_get_int(value);
-        gconf_value_free(value);
-    }
-    else
-        _route_dl_radius = 4;
-
-    /* Get Colors. */
-    {
-        gint i;
-        for(i = 0; i < COLORABLE_ENUM_COUNT; i++)
-        {
-            str = gconf_client_get_string(gconf_client,
-                    COLORABLE_GCONF[i], NULL);
-            if(!str || !gdk_color_parse(str, &_color[i]))
-                _color[i] = COLORABLE_DEFAULT[i];
-        }
-    }
-
-    /* Get current proxy settings. */
-    config_update_proxy();
-
-    gconf_client_clear_cache(gconf_client);
-    g_object_unref(gconf_client);
-    g_free(config_dir);
-
-    /* GPS data init */
-    _gps.fix = 1;
-    _gps.satinuse = 0;
-    _gps.satinview = 0;
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static void
-menu_maps_remove_repos()
-{
-    GList *curr;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    /* Delete one menu item for each repo. */
-    for(curr = _repo_list; curr; curr = curr->next)
-    {
-        gtk_widget_destroy(gtk_container_get_children(
-                    GTK_CONTAINER(_menu_maps_submenu))->data);
-    }
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static void
-menu_maps_add_repos()
-{
-    GList *curr;
-    GtkWidget *last_repo = NULL;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    for(curr = g_list_last(_repo_list); curr; curr = curr->prev)
-    {
-        RepoData *rd = (RepoData*)curr->data;
-        GtkWidget *menu_item;
-        if(last_repo)
-            gtk_menu_prepend(_menu_maps_submenu, menu_item
-                    = gtk_radio_menu_item_new_with_label_from_widget(
-                        GTK_RADIO_MENU_ITEM(last_repo), rd->name));
-        else
-        {
-            gtk_menu_prepend(_menu_maps_submenu, menu_item
-                    = gtk_radio_menu_item_new_with_label(NULL, rd->name));
-            last_repo = menu_item;
-        }
-        gtk_check_menu_item_set_active(
-                GTK_CHECK_MENU_ITEM(menu_item), rd == _curr_repo);
-        rd->menu_item = menu_item;
-    }
-
-    /* Add signals (must be after entire menu is built). */
-    {
-        GList *currmi = gtk_container_get_children(
-                GTK_CONTAINER(_menu_maps_submenu));
-        for(curr = _repo_list; curr; curr = curr->next, currmi = currmi->next)
-        {
-            g_signal_connect(G_OBJECT(currmi->data), "activate",
-                             G_CALLBACK(menu_cb_maps_select), curr->data);
-        }
-    }
-
-    gtk_widget_show_all(_menu_maps_submenu);
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-/**
- * Create the menu items needed for the drop down menu.
- */
-static void
-menu_init()
-{
-    /* Create needed handles. */
-    GtkMenu *menu;
-    GtkWidget *submenu;
-    GtkWidget *menu_item;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    /* Get the menu of our view. */
-    menu = GTK_MENU(gtk_menu_new());
-
-    /* Create the menu items. */
-
-    /* The "Routes" submenu. */
-    gtk_menu_append(menu, menu_item
-            = gtk_menu_item_new_with_label(_("Route")));
-    gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
-            submenu = gtk_menu_new());
-    gtk_menu_append(submenu, _menu_route_open_item
-            = gtk_menu_item_new_with_label(_("Open...")));
-    gtk_menu_append(submenu, _menu_route_download_item
-            = gtk_menu_item_new_with_label(_("Download...")));
-    gtk_menu_append(submenu, _menu_route_save_item
-            = gtk_menu_item_new_with_label(_("Save...")));
-    gtk_menu_append(submenu, _menu_route_distnext_item
-        = gtk_menu_item_new_with_label(_("Show Distance to Next Waypoint")));
-    gtk_menu_append(submenu, _menu_route_distlast_item
-        = gtk_menu_item_new_with_label(_("Show Distance to End of Route")));
-    gtk_menu_append(submenu, _menu_route_reset_item
-            = gtk_menu_item_new_with_label(_("Reset")));
-    gtk_menu_append(submenu, _menu_route_clear_item
-            = gtk_menu_item_new_with_label(_("Clear")));
-
-    /* The "Track" submenu. */
-    gtk_menu_append(menu, menu_item
-            = gtk_menu_item_new_with_label(_("Track")));
-    gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
-            submenu = gtk_menu_new());
-    gtk_menu_append(submenu, _menu_track_open_item
-            = gtk_menu_item_new_with_label(_("Open...")));
-    gtk_menu_append(submenu, _menu_track_save_item
-            = gtk_menu_item_new_with_label(_("Save...")));
-    gtk_menu_append(submenu, _menu_track_insert_break_item
-            = gtk_menu_item_new_with_label(_("Insert Break")));
-    gtk_menu_append(submenu, _menu_track_insert_mark_item
-            = gtk_menu_item_new_with_label(_("Insert Mark...")));
-    gtk_menu_append(submenu, _menu_track_distlast_item
-        = gtk_menu_item_new_with_label(_("Show Distance from Last Mark")));
-    gtk_menu_append(submenu, _menu_track_distfirst_item
-        = gtk_menu_item_new_with_label(_("Show Distance from Beginning")));
-    gtk_menu_append(submenu, _menu_track_clear_item
-            = gtk_menu_item_new_with_label(_("Clear")));
-
-    /* The "Maps" submenu. */
-    gtk_menu_append(menu, menu_item
-            = gtk_menu_item_new_with_label(_("Maps")));
-    gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
-            _menu_maps_submenu = gtk_menu_new());
-    gtk_menu_append(_menu_maps_submenu, gtk_separator_menu_item_new());
-    gtk_menu_append(_menu_maps_submenu, _menu_maps_mapman_item
-            = gtk_menu_item_new_with_label(_("Manage Maps...")));
-    gtk_menu_append(_menu_maps_submenu, _menu_maps_repoman_item
-            = gtk_menu_item_new_with_label(_("Manage Repositories...")));
-    gtk_menu_append(_menu_maps_submenu, _menu_auto_download_item
-            = gtk_check_menu_item_new_with_label(_("Auto-Download")));
-    gtk_check_menu_item_set_active(
-            GTK_CHECK_MENU_ITEM(_menu_auto_download_item), _auto_download);
-    menu_maps_add_repos(_curr_repo);
-
-    gtk_menu_append(menu, gtk_separator_menu_item_new());
-
-    /* The "View" submenu. */
-    gtk_menu_append(menu, menu_item
-            = gtk_menu_item_new_with_label(_("View")));
-    gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
-            submenu = gtk_menu_new());
-    gtk_menu_append(submenu, _menu_zoomin_item
-            = gtk_menu_item_new_with_label(_("Zoom In")));
-    gtk_menu_append(submenu, _menu_zoomout_item
-            = gtk_menu_item_new_with_label(_("Zoom Out")));
-    gtk_menu_append(submenu, _menu_fullscreen_item
-            = gtk_check_menu_item_new_with_label(_("Full Screen")));
-    gtk_check_menu_item_set_active(
-            GTK_CHECK_MENU_ITEM(_menu_fullscreen_item), _fullscreen);
-    gtk_menu_append(submenu, gtk_separator_menu_item_new());
-    gtk_menu_append(submenu, _menu_show_zoomlevel_item
-            = gtk_check_menu_item_new_with_label(_("Zoom Level")));
-    gtk_check_menu_item_set_active(
-            GTK_CHECK_MENU_ITEM(_menu_show_zoomlevel_item),
-            _show_zoomlevel);
-    gtk_menu_append(submenu, _menu_show_scale_item
-            = gtk_check_menu_item_new_with_label(_("Scale")));
-    gtk_check_menu_item_set_active(
-            GTK_CHECK_MENU_ITEM(_menu_show_scale_item),
-            _show_scale);
-    gtk_menu_append(submenu, _menu_show_routes_item
-            = gtk_check_menu_item_new_with_label(_("Route")));
-    gtk_check_menu_item_set_active(
-            GTK_CHECK_MENU_ITEM(_menu_show_routes_item),
-            _show_tracks & ROUTES_MASK);
-    gtk_menu_append(submenu, _menu_show_tracks_item
-            = gtk_check_menu_item_new_with_label(_("Track")));
-    gtk_check_menu_item_set_active(
-            GTK_CHECK_MENU_ITEM(_menu_show_tracks_item),
-            _show_tracks & TRACKS_MASK);
-    gtk_menu_append(submenu, _menu_show_velvec_item
-            = gtk_check_menu_item_new_with_label(_("Velocity Vector")));
-    gtk_check_menu_item_set_active(
-            GTK_CHECK_MENU_ITEM(_menu_show_velvec_item), _show_velvec);
-    gtk_menu_append(submenu, _menu_show_poi_item
-            = gtk_check_menu_item_new_with_label(_("POIs")));
-    gtk_check_menu_item_set_active(
-            GTK_CHECK_MENU_ITEM(_menu_show_poi_item), _show_poi);
-    gtk_menu_append(submenu, _menu_poi_item
-            = gtk_menu_item_new_with_label(_("POI Categories...")));
-    gtk_widget_set_sensitive(_menu_poi_item, _db != NULL);
-
-    /* The "Auto-Center" submenu. */
-    gtk_menu_append(menu, menu_item
-            = gtk_menu_item_new_with_label(_("Auto-Center")));
-    gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
-            submenu = gtk_menu_new());
-    gtk_menu_append(submenu, _menu_ac_latlon_item
-            = gtk_radio_menu_item_new_with_label(NULL, _("Lat/Lon")));
-    gtk_check_menu_item_set_active(
-            GTK_CHECK_MENU_ITEM(_menu_ac_latlon_item),
-            _center_mode == CENTER_LATLON);
-    gtk_menu_append(submenu, _menu_ac_lead_item
-            = gtk_radio_menu_item_new_with_label_from_widget(
-                GTK_RADIO_MENU_ITEM(_menu_ac_latlon_item), _("Lead")));
-    gtk_check_menu_item_set_active(
-            GTK_CHECK_MENU_ITEM(_menu_ac_lead_item),
-            _center_mode == CENTER_LEAD);
-    gtk_menu_append(submenu, _menu_ac_none_item
-            = gtk_radio_menu_item_new_with_label_from_widget(
-                GTK_RADIO_MENU_ITEM(_menu_ac_latlon_item), _("None")));
-    gtk_check_menu_item_set_active(
-            GTK_CHECK_MENU_ITEM(_menu_ac_none_item),
-            _center_mode < 0);
-
-    /* The "Go to" submenu. */
-    gtk_menu_append(menu, menu_item
-            = gtk_menu_item_new_with_label(_("Go to")));
-    gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
-            submenu = gtk_menu_new());
-    gtk_menu_append(submenu, _menu_goto_latlon
-            = gtk_menu_item_new_with_label(_("Lat/Lon...")));
-    gtk_menu_append(submenu, _menu_goto_address
-            = gtk_menu_item_new_with_label(_("Address...")));
-    gtk_menu_append(submenu, _menu_goto_gps
-            = gtk_menu_item_new_with_label(_("GPS Location")));
-    gtk_menu_append(submenu, _menu_goto_nextway
-            = gtk_menu_item_new_with_label(_("Next Waypoint")));
-    gtk_menu_append(submenu, _menu_goto_nearpoi
-            = gtk_menu_item_new_with_label(_("Nearest POI")));
-
-    /* The "GPS" submenu. */
-    gtk_menu_append(menu, menu_item
-            = gtk_menu_item_new_with_label(_("GPS")));
-    gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
-            submenu = gtk_menu_new());
-    gtk_menu_append(submenu, _menu_enable_gps_item
-            = gtk_check_menu_item_new_with_label(_("Enable GPS")));
-    gtk_check_menu_item_set_active(
-            GTK_CHECK_MENU_ITEM(_menu_enable_gps_item), _enable_gps);
-    gtk_menu_append(submenu, _menu_gps_show_info_item
-            = gtk_check_menu_item_new_with_label(_("Show Information")));
-    gtk_check_menu_item_set_active(
-            GTK_CHECK_MENU_ITEM(_menu_gps_show_info_item), _gps_info);
-    gtk_menu_append(submenu, _menu_gps_details_item
-            = gtk_menu_item_new_with_label(_("Details...")));
-    gtk_widget_set_sensitive(GTK_WIDGET(_menu_gps_details_item), _enable_gps);
-    gtk_menu_append(submenu, _menu_gps_reset_item
-        = gtk_menu_item_new_with_label(_("Reset Bluetooth")));
-    gtk_widget_set_sensitive(GTK_WIDGET(_menu_gps_reset_item), _enable_gps);
-
-    gtk_menu_append(menu, gtk_separator_menu_item_new());
-
-    /* The other menu items. */
-    gtk_menu_append(menu, _menu_settings_item
-        = gtk_menu_item_new_with_label(_("Settings...")));
-    gtk_menu_append(menu, gtk_separator_menu_item_new());
-    gtk_menu_append(menu, _menu_help_item
-        = gtk_menu_item_new_with_label(_("Help...")));
-    gtk_menu_append(menu, _menu_about_item
-        = gtk_menu_item_new_with_label(_("About...")));
-    gtk_menu_append(menu, _menu_close_item
-        = gtk_menu_item_new_with_label(_("Close")));
-
-    /* We need to show menu items. */
-    gtk_widget_show_all(GTK_WIDGET(menu));
-
-    hildon_window_set_menu(HILDON_WINDOW(_window), menu);
-
-    /* Connect the "Route" signals. */
-    g_signal_connect(G_OBJECT(_menu_route_open_item), "activate",
-                      G_CALLBACK(menu_cb_route_open), NULL);
-    g_signal_connect(G_OBJECT(_menu_route_download_item), "activate",
-                      G_CALLBACK(menu_cb_route_download), NULL);
-    g_signal_connect(G_OBJECT(_menu_route_save_item), "activate",
-                      G_CALLBACK(menu_cb_route_save), NULL);
-    g_signal_connect(G_OBJECT(_menu_route_distnext_item), "activate",
-                      G_CALLBACK(menu_cb_route_distnext), NULL);
-    g_signal_connect(G_OBJECT(_menu_route_distlast_item), "activate",
-                      G_CALLBACK(menu_cb_route_distlast), NULL);
-    g_signal_connect(G_OBJECT(_menu_route_reset_item), "activate",
-                      G_CALLBACK(menu_cb_route_reset), NULL);
-    g_signal_connect(G_OBJECT(_menu_route_clear_item), "activate",
-                      G_CALLBACK(menu_cb_route_clear), NULL);
-
-    /* Connect the "Track" signals. */
-    g_signal_connect(G_OBJECT(_menu_track_open_item), "activate",
-                      G_CALLBACK(menu_cb_track_open), NULL);
-    g_signal_connect(G_OBJECT(_menu_track_save_item), "activate",
-                      G_CALLBACK(menu_cb_track_save), NULL);
-    g_signal_connect(G_OBJECT(_menu_track_insert_break_item), "activate",
-                      G_CALLBACK(menu_cb_track_insert_break), NULL);
-    g_signal_connect(G_OBJECT(_menu_track_insert_mark_item), "activate",
-                      G_CALLBACK(menu_cb_track_insert_mark), NULL);
-    g_signal_connect(G_OBJECT(_menu_track_distlast_item), "activate",
-                      G_CALLBACK(menu_cb_track_distlast), NULL);
-    g_signal_connect(G_OBJECT(_menu_track_distfirst_item), "activate",
-                      G_CALLBACK(menu_cb_track_distfirst), NULL);
-    g_signal_connect(G_OBJECT(_menu_track_clear_item), "activate",
-                      G_CALLBACK(menu_cb_track_clear), NULL);
-
-    /* Connect the "Maps" signals. */
-    g_signal_connect(G_OBJECT(_menu_maps_repoman_item), "activate",
-                      G_CALLBACK(menu_cb_maps_repoman), NULL);
-    g_signal_connect(G_OBJECT(_menu_maps_mapman_item), "activate",
-                      G_CALLBACK(menu_cb_mapman), NULL);
-
-    /* Connect the "View" signals. */
-    g_signal_connect(G_OBJECT(_menu_zoomin_item), "activate",
-                      G_CALLBACK(menu_cb_zoomin), NULL);
-    g_signal_connect(G_OBJECT(_menu_zoomout_item), "activate",
-                      G_CALLBACK(menu_cb_zoomout), NULL);
-    g_signal_connect(G_OBJECT(_menu_fullscreen_item), "toggled",
-                      G_CALLBACK(menu_cb_fullscreen), NULL);
-    g_signal_connect(G_OBJECT(_menu_show_tracks_item), "toggled",
-                      G_CALLBACK(menu_cb_show_tracks), NULL);
-    g_signal_connect(G_OBJECT(_menu_show_zoomlevel_item), "toggled",
-                      G_CALLBACK(menu_cb_show_zoomlevel), NULL);
-    g_signal_connect(G_OBJECT(_menu_show_scale_item), "toggled",
-                      G_CALLBACK(menu_cb_show_scale), NULL);
-    g_signal_connect(G_OBJECT(_menu_show_routes_item), "toggled",
-                      G_CALLBACK(menu_cb_show_routes), NULL);
-    g_signal_connect(G_OBJECT(_menu_show_velvec_item), "toggled",
-                      G_CALLBACK(menu_cb_show_velvec), NULL);
-    g_signal_connect(G_OBJECT(_menu_show_poi_item), "toggled",
-                      G_CALLBACK(menu_cb_show_poi), NULL);
-    g_signal_connect(G_OBJECT(_menu_poi_item), "activate",
-                      G_CALLBACK(menu_cb_category), NULL);
-
-    /* Connect the "Auto-Center" signals. */
-    g_signal_connect(G_OBJECT(_menu_ac_latlon_item), "toggled",
-                      G_CALLBACK(menu_cb_ac_latlon), NULL);
-    g_signal_connect(G_OBJECT(_menu_ac_lead_item), "toggled",
-                      G_CALLBACK(menu_cb_ac_lead), NULL);
-    g_signal_connect(G_OBJECT(_menu_ac_none_item), "toggled",
-                      G_CALLBACK(menu_cb_ac_none), NULL);
-
-    /* Connect the "Go to" signals. */
-    g_signal_connect(G_OBJECT(_menu_goto_latlon), "activate",
-                      G_CALLBACK(menu_cb_goto_latlon), NULL);
-    g_signal_connect(G_OBJECT(_menu_goto_address), "activate",
-                      G_CALLBACK(menu_cb_goto_address), NULL);
-    g_signal_connect(G_OBJECT(_menu_goto_gps), "activate",
-                      G_CALLBACK(menu_cb_goto_gps), NULL);
-    g_signal_connect(G_OBJECT(_menu_goto_nextway), "activate",
-                      G_CALLBACK(menu_cb_goto_nextway), NULL);
-    g_signal_connect(G_OBJECT(_menu_goto_nearpoi), "activate",
-                      G_CALLBACK(menu_cb_goto_nearpoi), NULL);
-
-    /* Connect the "GPS" signals. */
-    g_signal_connect(G_OBJECT(_menu_enable_gps_item), "toggled",
-                      G_CALLBACK(menu_cb_enable_gps), NULL);
-    g_signal_connect(G_OBJECT(_menu_gps_show_info_item), "toggled",
-                      G_CALLBACK(menu_cb_gps_show_info), NULL);
-    g_signal_connect(G_OBJECT(_menu_gps_details_item), "activate",
-                      G_CALLBACK(menu_cb_gps_details), NULL);
-    g_signal_connect(G_OBJECT(_menu_gps_reset_item), "activate",
-                      G_CALLBACK(menu_cb_gps_reset), NULL);
-    g_signal_connect(G_OBJECT(_menu_auto_download_item), "toggled",
-                      G_CALLBACK(menu_cb_auto_download), NULL);
-
-    /* Connect the other menu item signals. */
-    g_signal_connect(G_OBJECT(_menu_settings_item), "activate",
-                      G_CALLBACK(menu_cb_settings), NULL);
-    g_signal_connect(G_OBJECT(_menu_help_item), "activate",
-                      G_CALLBACK(menu_cb_help), NULL);
-    g_signal_connect(G_OBJECT(_menu_about_item), "activate",
-                      G_CALLBACK(menu_cb_about), NULL);
-    g_signal_connect(G_OBJECT(_menu_close_item), "activate",
-                      G_CALLBACK(gtk_main_quit), NULL);
-
-    /* Setup the context menu. */
-    menu = GTK_MENU(gtk_menu_new());
-
-    /* Setup the map context menu. */
-    gtk_menu_append(menu, menu_item
-            = gtk_menu_item_new_with_label(_("Location")));
-    gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
-            submenu = gtk_menu_new());
-
-    /* Setup the map context menu. */
-    gtk_menu_append(submenu, _cmenu_loc_show_latlon_item
-            = gtk_menu_item_new_with_label(_("Show Lat/Lon")));
-    gtk_menu_append(submenu, gtk_separator_menu_item_new());
-    gtk_menu_append(submenu, _cmenu_loc_distance_to_item
-            = gtk_menu_item_new_with_label(_("Show Distance to")));
-    gtk_menu_append(submenu, _cmenu_loc_route_to_item
-            = gtk_menu_item_new_with_label(_("Download Route to...")));
-    gtk_menu_append(submenu, gtk_separator_menu_item_new());
-    gtk_menu_append(submenu, _cmenu_loc_add_route
-                = gtk_menu_item_new_with_label(_("Add Route Point")));
-    gtk_menu_append(submenu, _cmenu_loc_add_way
-                = gtk_menu_item_new_with_label(_("Add Waypoint...")));
-    gtk_menu_append(submenu, _cmenu_loc_add_poi
-                = gtk_menu_item_new_with_label(_("Add POI...")));
-    gtk_widget_set_sensitive(_cmenu_loc_add_poi, _db != NULL);
-    gtk_menu_append(submenu, gtk_separator_menu_item_new());
-    gtk_menu_append(submenu, _cmenu_loc_set_gps
-                = gtk_menu_item_new_with_label(_("Set as GPS Location")));
-
-    /* Setup the waypoint context menu. */
-    gtk_menu_append(menu, menu_item
-            = gtk_menu_item_new_with_label(_("Waypoint")));
-    gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
-            submenu = gtk_menu_new());
-
-    gtk_menu_append(submenu, _cmenu_way_show_latlon_item
-            = gtk_menu_item_new_with_label(_("Show Lat/Lon")));
-    gtk_menu_append(submenu, _cmenu_way_show_desc_item
-            = gtk_menu_item_new_with_label(_("Show Description")));
-    gtk_menu_append(submenu, _cmenu_way_clip_latlon_item
-            = gtk_menu_item_new_with_label(_("Copy Lat/Lon")));
-    gtk_menu_append(submenu, _cmenu_way_clip_desc_item
-            = gtk_menu_item_new_with_label(_("Copy Description")));
-    gtk_menu_append(submenu, gtk_separator_menu_item_new());
-    gtk_menu_append(submenu, _cmenu_way_distance_to_item
-            = gtk_menu_item_new_with_label(_("Show Distance to")));
-    gtk_menu_append(submenu, _cmenu_way_route_to_item
-            = gtk_menu_item_new_with_label(_("Download Route to...")));
-    gtk_menu_append(submenu, _cmenu_way_delete_item
-            = gtk_menu_item_new_with_label(_("Delete...")));
-    gtk_menu_append(submenu, gtk_separator_menu_item_new());
-    gtk_menu_append(submenu, _cmenu_way_add_poi
-                = gtk_menu_item_new_with_label(_("Add POI...")));
-    gtk_widget_set_sensitive(_cmenu_way_add_poi, _db != NULL);
-    gtk_menu_append(submenu, gtk_separator_menu_item_new());
-    gtk_menu_append(submenu, _cmenu_way_goto_nextway
-                = gtk_menu_item_new_with_label(_("Go to Next")));
-
-    /* Setup the POI context menu. */
-    gtk_menu_append(menu, _cmenu_poi
-            = gtk_menu_item_new_with_label(_("POI")));
-    gtk_widget_set_sensitive(_cmenu_poi, _db != NULL);
-    gtk_menu_item_set_submenu(GTK_MENU_ITEM(_cmenu_poi),
-            submenu = gtk_menu_new());
-
-    gtk_menu_append(submenu, _cmenu_poi_edit_poi
-                = gtk_menu_item_new_with_label(_("View/Edit...")));
-    gtk_menu_append(submenu, gtk_separator_menu_item_new());
-    gtk_menu_append(submenu, _cmenu_poi_distance_to_item
-            = gtk_menu_item_new_with_label(_("Show Distance to")));
-    gtk_menu_append(submenu, _cmenu_poi_route_to_item
-            = gtk_menu_item_new_with_label(_("Download Route to...")));
-    gtk_menu_append(submenu, gtk_separator_menu_item_new());
-    gtk_menu_append(submenu, _cmenu_poi_add_route
-                = gtk_menu_item_new_with_label(_("Add Route Point")));
-    gtk_menu_append(submenu, _cmenu_poi_add_way
-                = gtk_menu_item_new_with_label(_("Add Waypoint...")));
-    gtk_menu_append(submenu, gtk_separator_menu_item_new());
-    gtk_menu_append(submenu, _cmenu_poi_goto_nearpoi
-                = gtk_menu_item_new_with_label(_("Go to Nearest")));
-
-    /* Connect signals for context menu. */
-    g_signal_connect(G_OBJECT(_cmenu_loc_show_latlon_item), "activate",
-                      G_CALLBACK(cmenu_cb_loc_show_latlon), NULL);
-    g_signal_connect(G_OBJECT(_cmenu_loc_route_to_item), "activate",
-                      G_CALLBACK(cmenu_cb_loc_route_to), NULL);
-    g_signal_connect(G_OBJECT(_cmenu_loc_distance_to_item), "activate",
-                      G_CALLBACK(cmenu_cb_loc_distance_to), NULL);
-    g_signal_connect(G_OBJECT(_cmenu_loc_add_route), "activate",
-                        G_CALLBACK(cmenu_cb_loc_add_route), NULL);
-    g_signal_connect(G_OBJECT(_cmenu_loc_add_way), "activate",
-                        G_CALLBACK(cmenu_cb_loc_add_way), NULL);
-    g_signal_connect(G_OBJECT(_cmenu_loc_add_poi), "activate",
-                        G_CALLBACK(cmenu_cb_loc_add_poi), NULL);
-    g_signal_connect(G_OBJECT(_cmenu_loc_set_gps), "activate",
-                        G_CALLBACK(cmenu_cb_loc_set_gps), NULL);
-
-    g_signal_connect(G_OBJECT(_cmenu_way_show_latlon_item), "activate",
-                      G_CALLBACK(cmenu_cb_way_show_latlon), NULL);
-    g_signal_connect(G_OBJECT(_cmenu_way_show_desc_item), "activate",
-                      G_CALLBACK(cmenu_cb_way_show_desc), NULL);
-    g_signal_connect(G_OBJECT(_cmenu_way_clip_latlon_item), "activate",
-                      G_CALLBACK(cmenu_cb_way_clip_latlon), NULL);
-    g_signal_connect(G_OBJECT(_cmenu_way_clip_desc_item), "activate",
-                      G_CALLBACK(cmenu_cb_way_clip_desc), NULL);
-    g_signal_connect(G_OBJECT(_cmenu_way_route_to_item), "activate",
-                      G_CALLBACK(cmenu_cb_way_route_to), NULL);
-    g_signal_connect(G_OBJECT(_cmenu_way_distance_to_item), "activate",
-                      G_CALLBACK(cmenu_cb_way_distance_to), NULL);
-    g_signal_connect(G_OBJECT(_cmenu_way_delete_item), "activate",
-                      G_CALLBACK(cmenu_cb_way_delete), NULL);
-    g_signal_connect(G_OBJECT(_cmenu_way_add_poi), "activate",
-                        G_CALLBACK(cmenu_cb_way_add_poi), NULL);
-    g_signal_connect(G_OBJECT(_cmenu_way_goto_nextway), "activate",
-                        G_CALLBACK(menu_cb_goto_nextway), NULL);
-
-    g_signal_connect(G_OBJECT(_cmenu_poi_edit_poi), "activate",
-                        G_CALLBACK(cmenu_cb_poi_edit_poi), NULL);
-    g_signal_connect(G_OBJECT(_cmenu_poi_route_to_item), "activate",
-                      G_CALLBACK(cmenu_cb_poi_route_to), NULL);
-    g_signal_connect(G_OBJECT(_cmenu_poi_distance_to_item), "activate",
-                      G_CALLBACK(cmenu_cb_poi_distance_to), NULL);
-    g_signal_connect(G_OBJECT(_cmenu_poi_add_route), "activate",
-                        G_CALLBACK(cmenu_cb_poi_add_route), NULL);
-    g_signal_connect(G_OBJECT(_cmenu_poi_add_way), "activate",
-                        G_CALLBACK(cmenu_cb_poi_add_way), NULL);
-    g_signal_connect(G_OBJECT(_cmenu_poi_goto_nearpoi), "activate",
-                        G_CALLBACK(menu_cb_goto_nearpoi), NULL);
-
-    gtk_widget_show_all(GTK_WIDGET(menu));
-
-    gtk_widget_tap_and_hold_setup(_map_widget, GTK_WIDGET(menu), NULL, 0);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-/**
- * Call gtk_window_present() on Maemo Mapper.  This also checks the
- * configuration and brings up the Settings dialog if the GPS Receiver is
- * not set up, the first time it is called.
- */
-static gboolean
-window_present()
-{
-    static gint been_here = 0;
-    static gint done_here = 0;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(!been_here++)
-    {
-        /* Set connection state first, to avoid going into this if twice. */
-        if(!_rcvr_mac && _enable_gps)
-        {
-            GtkWidget *confirm;
-
-            gtk_window_present(GTK_WINDOW(_window));
-
-            confirm = hildon_note_new_confirmation(GTK_WINDOW(_window),
-                    _("It looks like this is your first time running"
-                        " Maemo Mapper.  Press OK to view the the help pages."
-                        " Otherwise, press Cancel to continue."));
-
-            if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm)))
-                ossohelp_show(_osso, HELP_ID_INTRO, 0);
-            gtk_widget_destroy(confirm);
-            if(settings_dialog())
-            {
-                popup_error(_window,
-                    _("OpenStreetMap.org provides public, free-to-use maps.  "
-                    "You can also download a sample set of repositories from "
-                    " the internet by using the \"Download...\" button."));
-                repoman_dialog();
-                if(_curr_repo->type != REPOTYPE_NONE)
-                {
-                    confirm = hildon_note_new_confirmation(GTK_WINDOW(_window),
-                        _("You will now see a blank screen.  You can download"
-                            " maps using the \"Manage Maps\" menu item in the"
-                            " \"Maps\" menu.  Or, press OK to enable"
-                            " Auto-Download."));
-                    if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm)))
-                    {
-                        gtk_check_menu_item_set_active(
-                                GTK_CHECK_MENU_ITEM(_menu_auto_download_item),
-                            TRUE);
-                    }
-                    gtk_widget_destroy(confirm);
-                }
-            }
-            else
-                gtk_main_quit();
-        }
-        /* Connect to receiver. */
-        if(_enable_gps)
-            rcvr_connect_now();
-
-        done_here++; /* Don't ask... */
-    }
-    if(done_here)
-    {
-        gtk_window_present(GTK_WINDOW(_window));
-
-        /* Re-enable any banners that might have been up. */
-        {
-            ConnState old_state = _conn_state;
-            set_conn_state(RCVR_OFF);
-            set_conn_state(old_state);
-        }
-    }
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-    return FALSE;
-}
-
-/**
- * Draw the current mark (representing the current GPS location) onto
- * _map_widget.  This method does not queue the draw area.
- */
-static void
-map_draw_mark()
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    gdk_draw_arc(
-            _map_widget->window,
-            _conn_state == RCVR_FIXED
-                ? _gc[COLORABLE_MARK] : _gc[COLORABLE_MARK_OLD],
-            FALSE, /* not filled. */
-            _mark_x1 - _draw_width, _mark_y1 - _draw_width,
-            2 * _draw_width, 2 * _draw_width,
-            0, 360 * 64);
-    gdk_draw_line(
-            _map_widget->window,
-            _conn_state == RCVR_FIXED
-                ? (_show_velvec
-                    ? _gc[COLORABLE_MARK_VELOCITY] : _gc[COLORABLE_MARK])
-                : _gc[COLORABLE_MARK_OLD],
-            _mark_x1, _mark_y1, _mark_x2, _mark_y2);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-/**
- * "Set" the mark, which translates the current GPS position into on-screen
- * units in preparation for drawing the mark with map_draw_mark().
- */
-static void map_set_mark()
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    _mark_x1 = unit2x(_pos.unitx);
-    _mark_y1 = unit2y(_pos.unity);
-    _mark_x2 = _mark_x1 + (_show_velvec ? _vel_offsetx : 0);
-    _mark_y2 = _mark_y1 + (_show_velvec ? _vel_offsety : 0);
-    _mark_minx = MIN(_mark_x1, _mark_x2) - (2 * _draw_width);
-    _mark_miny = MIN(_mark_y1, _mark_y2) - (2 * _draw_width);
-    _mark_width = abs(_mark_x1 - _mark_x2) + (4 * _draw_width);
-    _mark_height = abs(_mark_y1 - _mark_y2) + (4 * _draw_width);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-/**
- * Do an in-place scaling of a pixbuf's pixels at the given ratio from the
- * given source location.  It would have been nice if gdk_pixbuf provided
- * this method, but I guess it's not general-purpose enough.
- */
-static void
-map_pixbuf_scale_inplace(GdkPixbuf* pixbuf, guint ratio_p2,
-        guint src_x, guint src_y)
-{
-    guint dest_x = 0, dest_y = 0, dest_dim = TILE_SIZE_PIXELS;
-    guint rowstride = gdk_pixbuf_get_rowstride(pixbuf);
-    guint n_channels = gdk_pixbuf_get_n_channels(pixbuf);
-    guchar* pixels = gdk_pixbuf_get_pixels(pixbuf);
-    vprintf("%s(%d, %d, %d)\n", __PRETTY_FUNCTION__, ratio_p2, src_x, src_y);
-
-    /* Sweep through the entire dest area, copying as necessary, but
-     * DO NOT OVERWRITE THE SOURCE AREA.  We'll copy it afterward. */
-    do {
-        guint src_dim = dest_dim >> ratio_p2;
-        guint src_endx = src_x - dest_x + src_dim;
-        gint x, y;
-        for(y = dest_dim - 1; y >= 0; y--)
-        {
-            guint src_offset_y, dest_offset_y;
-            src_offset_y = (src_y + (y >> ratio_p2)) * rowstride;
-            dest_offset_y = (dest_y + y) * rowstride;
-            x = dest_dim - 1;
-            if((unsigned)(dest_y + y - src_y) < src_dim
-                    && (unsigned)(dest_x + x - src_x) < src_dim)
-                x -= src_dim;
-            for(; x >= 0; x--)
-            {
-                guint src_offset, dest_offset, i;
-                src_offset = src_offset_y + (src_x+(x>>ratio_p2)) * n_channels;
-                dest_offset = dest_offset_y + (dest_x + x) * n_channels;
-                pixels[dest_offset] = pixels[src_offset];
-                for(i = n_channels - 1; i; --i) /* copy other channels */
-                    pixels[dest_offset + i] = pixels[src_offset + i];
-                if((unsigned)(dest_y + y - src_y) < src_dim && x == src_endx)
-                    x -= src_dim;
-            }
-        }
-        /* Reuse src_dim and src_endx to store new src_x and src_y. */
-        src_dim = src_x + ((src_x - dest_x) >> ratio_p2);
-        src_endx = src_y + ((src_y - dest_y) >> ratio_p2);
-        dest_x = src_x;
-        dest_y = src_y;
-        src_x = src_dim;
-        src_y = src_endx;
-    }
-    while((dest_dim >>= ratio_p2) > 1);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-/**
- * Trim pixbufs that are bigger than tiles. (Those pixbufs result, when
- * captions should be cut off.)
- */
-static GdkPixbuf*
-pixbuf_trim(GdkPixbuf* pixbuf)
-{
-    vprintf("%s()\n", __PRETTY_FUNCTION__);
-    GdkPixbuf* mpixbuf = gdk_pixbuf_new(
-            GDK_COLORSPACE_RGB, gdk_pixbuf_get_has_alpha(pixbuf),
-            8, TILE_SIZE_PIXELS, TILE_SIZE_PIXELS);
-
-    gdk_pixbuf_copy_area(pixbuf,
-            (gdk_pixbuf_get_width(pixbuf) - TILE_SIZE_PIXELS) / 2,
-            (gdk_pixbuf_get_height(pixbuf) - TILE_SIZE_PIXELS) / 2,
-            TILE_SIZE_PIXELS, TILE_SIZE_PIXELS,
-            mpixbuf,
-            0, 0);
-
-    g_object_unref(pixbuf);
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-    return mpixbuf;
-}
-
-
-/**
- * Given a wms uri pattern, compute the coordinate transformation and
- * trimming.
- * 'proj' is used for the conversion
- */
-static gchar*
-map_convert_wms_to_wms(gint tilex, gint tiley, gint zoomlevel, gchar* uri)
-{
-    gint system_retcode;
-    gchar cmd[BUFFER_SIZE], srs[BUFFER_SIZE];
-    gchar *ret = NULL;
-    FILE* in;
-    gfloat lon1, lat1, lon2, lat2;
-
-    gchar *widthstr   = strcasestr(uri,"WIDTH=");
-    gchar *heightstr  = strcasestr(uri,"HEIGHT=");
-    gchar *srsstr     = strcasestr(uri,"SRS=EPSG");
-    gchar *srsstre    = strchr(srsstr,'&');
-    vprintf("%s()\n", __PRETTY_FUNCTION__);
-
-    /* missing: test if found */
-    strcpy(srs,"epsg");
-    strncpy(srs+4,srsstr+8,256);
-    /* missing: test srsstre-srsstr < 526 */
-    srs[srsstre-srsstr-4] = 0;
-    /* convert to lower, as WMC is EPSG and cs2cs is epsg */
-
-    gint dwidth  = widthstr ? atoi(widthstr+6) - TILE_SIZE_PIXELS : 0;
-    gint dheight = heightstr ? atoi(heightstr+7) - TILE_SIZE_PIXELS : 0;
-
-    unit2latlon(tile2zunit(tilex,zoomlevel)
-            - pixel2zunit(dwidth/2,zoomlevel),
-            tile2zunit(tiley+1,zoomlevel)
-            + pixel2zunit((dheight+1)/2,zoomlevel),
-            lat1, lon1);
-
-    unit2latlon(tile2zunit(tilex+1,zoomlevel)
-            + pixel2zunit((dwidth+1)/2,zoomlevel),
-            tile2zunit(tiley,zoomlevel)
-            - pixel2zunit(dheight/2,zoomlevel),
-            lat2, lon2);
-
-    setlocale(LC_NUMERIC, "C");
-
-    snprintf(cmd, sizeof(cmd),
-            "(echo \"%.6f %.6f\"; echo \"%.6f %.6f\") | "
-            "/usr/bin/cs2cs +proj=longlat +datum=WGS84 +to +init=%s -f %%.6f "
-            " > /tmp/tmpcs2cs ",
-            lon1, lat1, lon2, lat2, srs);
-    vprintf("Running command: %s\n", cmd);
-    system_retcode = system(cmd);
-
-    if(system_retcode)
-        g_printerr("cs2cs returned error code %d\n",
-                WEXITSTATUS(system_retcode));
-    else if(!(in = g_fopen("/tmp/tmpcs2cs","r")))
-        g_printerr("Cannot open results of conversion\n");
-    else if(5 != fscanf(in,"%f %f %s %f %f", &lon1, &lat1, cmd, &lon2, &lat2))
-    {
-        g_printerr("Wrong conversion\n");
-        fclose(in);
-    }
-    else
-    {
-        fclose(in);
-        ret = g_strdup_printf(uri, lon1, lat1, lon2, lat2);
-    }
-
-    setlocale(LC_NUMERIC, "");
-
-    vprintf("%s(): return %s\n", __PRETTY_FUNCTION__, ret);
-    return ret;
-}
-
-
-/**
- * Given the xyz coordinates of our map coordinate system, write the qrst
- * quadtree coordinates to buffer.
- */
-static void
-map_convert_coords_to_quadtree_string(gint x, gint y, gint zoomlevel,
-                                      gchar *buffer, const gchar initial,
-                                      const gchar *const quadrant)
-{
-    gchar *ptr = buffer;
-    gint n;
-    vprintf("%s()\n", __PRETTY_FUNCTION__);
-
-    if (initial)
-        *ptr++ = initial;
-
-    for(n = 16 - zoomlevel; n >= 0; n--)
-    {
-        gint xbit = (x >> n) & 1;
-        gint ybit = (y >> n) & 1;
-        *ptr++ = quadrant[xbit + 2 * ybit];
-    }
-    *ptr++ = '\0';
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-/**
- * Construct the URL that we should fetch, based on the current URI format.
- * This method works differently depending on if a "%s" string is present in
- * the URI format, since that would indicate a quadtree-based map coordinate
- * system.
- */
-static gchar*
-map_construct_url(guint tilex, guint tiley, guint zoom)
-{
-    vprintf("%s()\n", __PRETTY_FUNCTION__);
-    switch(_curr_repo->type)
-    {
-        case REPOTYPE_XYZ:
-            return g_strdup_printf(_curr_repo->url, tilex, tiley, zoom);
-
-        case REPOTYPE_XYZ_INV:
-            return g_strdup_printf(_curr_repo->url, 17 - zoom, tilex, tiley);
-
-        case REPOTYPE_QUAD_QRST:
-        {
-            gchar location[MAX_ZOOM + 2];
-            map_convert_coords_to_quadtree_string(
-                    tilex, tiley, zoom, location, 't', "qrts");
-            return g_strdup_printf(_curr_repo->url, location);
-        }
-
-        case REPOTYPE_QUAD_ZERO:
-        {
-            /* This is a zero-based quadtree URI. */
-            gchar location[MAX_ZOOM + 2];
-            map_convert_coords_to_quadtree_string(
-                    tilex, tiley, zoom, location, '\0', "0123");
-            return g_strdup_printf(_curr_repo->url, location);
-        }
-
-        case REPOTYPE_WMS:
-            return map_convert_wms_to_wms(tilex, tiley, zoom, _curr_repo->url);
-
-        default:
-            return NULL;
-    }
-    vprintf("%s(): ERROR\n", __PRETTY_FUNCTION__);
-    return "";
-}
-
-/**
- * Initiate a download of the given xyz coordinates using the given buffer
- * as the URL.  If the map already exists on disk, or if we are already
- * downloading the map, then this method does nothing.
- */
-static void
-map_initiate_download(guint tilex, guint tiley, guint zoom, gint retries)
-{
-    ProgressUpdateInfo *pui;
-    vprintf("%s(%u, %u, %u, %d)\n", __PRETTY_FUNCTION__, tilex, tiley, zoom,
-            retries);
-
-    if(!_iap_connected && !_iap_connecting)
-    {
-        _iap_connecting = TRUE;
-        osso_iap_connect(OSSO_IAP_ANY, OSSO_IAP_REQUESTED_CONNECT, NULL);
-    }
-
-    pui = g_slice_new(ProgressUpdateInfo);
-    pui->tilex = tilex;
-    pui->tiley = tiley;
-    pui->zoom = zoom;
-    pui->priority = (abs((gint)tilex - unit2tile(_center.unitx))
-            + abs((gint)tiley - unit2tile(_center.unity)));
-    if(!retries)
-        pui->priority = -pui->priority; /* "Negative" makes them lowest pri. */
-    pui->retries = retries;
-    pui->repo = _curr_repo;
-
-    if(g_tree_lookup(_pui_tree, pui) || g_tree_lookup(_downloading_tree, pui))
-    {
-        /* Already downloading. */
-        g_slice_free(ProgressUpdateInfo, pui);
-        return;
-    }
-    pui->src_str = NULL;
-    pui->dest_str = NULL;
-    pui->file = NULL;
-
-    g_tree_insert(_pui_tree, pui, pui);
-    if(_iap_connected && !_curl_sid)
-        _curl_sid = g_timeout_add(100,
-                (GSourceFunc)curl_download_timeout, NULL);
-
-    if(!_num_downloads++ && !_download_banner)
-        _download_banner = hildon_banner_show_progress(
-                _window, NULL, _("Downloading maps"));
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-/**
- * Render all the POI data.  This should be done before rendering track data.
- */
-static void
-map_render_poi()
-{
-    guint unitx, unity;
-    gfloat lat1, lat2, lon1, lon2;
-    gchar buffer[100];
-    gint poix, poiy;
-    GdkPixbuf *pixbuf = NULL;
-    GError *error = NULL;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(_db && _poi_zoom > _zoom)
-    {
-        unitx = x2unit(0);
-        unity = y2unit(BUF_HEIGHT_PIXELS);
-        unit2latlon(unitx, unity, lat1, lon1);
-        unitx = x2unit(BUF_WIDTH_PIXELS);
-        unity = y2unit(0);
-        unit2latlon(unitx, unity, lat2, lon2);
-
-        if(SQLITE_OK != sqlite3_bind_double(_stmt_select_poi, 1, lat1) ||
-           SQLITE_OK != sqlite3_bind_double(_stmt_select_poi, 2, lat2) ||
-           SQLITE_OK != sqlite3_bind_double(_stmt_select_poi, 3, lon1) ||
-           SQLITE_OK != sqlite3_bind_double(_stmt_select_poi, 4, lon2))
-        {
-            g_printerr("Failed to bind values for _stmt_select_poi\n");
-            return;
-        }
-
-        while(SQLITE_ROW == sqlite3_step(_stmt_select_poi))
-        {
-            lat1 = sqlite3_column_double(_stmt_select_poi, 0);
-            lon1 = sqlite3_column_double(_stmt_select_poi, 1);
-            gchar *poi_label = g_utf8_strdown(sqlite3_column_text(
-                    _stmt_select_poi, 3), -1);
-            gchar *cat_label = g_utf8_strdown(sqlite3_column_text(
-                    _stmt_select_poi, 6), -1);
-
-            latlon2unit(lat1, lon1, unitx, unity);
-            poix = unit2bufx(unitx);
-            poiy = unit2bufy(unity);
-
-            /* Try to get icon for specific POI first. */
-            snprintf(buffer, sizeof(buffer), "%s/poi/%s.jpg",
-                    _curr_repo->cache_dir, poi_label);
-            pixbuf = gdk_pixbuf_new_from_file(buffer, &error);
-            if(error)
-            {
-                /* No icon for specific POI - try for category. */
-                error = NULL;
-                snprintf(buffer, sizeof(buffer), "%s/poi/%s.jpg",
-                        _curr_repo->cache_dir, cat_label);
-                pixbuf = gdk_pixbuf_new_from_file(buffer, &error);
-            }
-            if(error)
-            {
-                /* No icon for POI or for category.
-                 * Try default POI icon file. */
-                error = NULL;
-                snprintf(buffer, sizeof(buffer), "%s/poi/poi.jpg",
-                        _curr_repo->cache_dir);
-                pixbuf = gdk_pixbuf_new_from_file(buffer, &error);
-            }
-            if(error)
-            {
-                /* No icon for POI or for category or default POI icon file.
-                   Draw default purple square. */
-                error = NULL;
-                gdk_draw_rectangle(_map_pixmap, _gc[COLORABLE_POI], TRUE,
-                        poix - (gint)(1.5f * _draw_width),
-                        poiy - (gint)(1.5f * _draw_width),
-                        3 * _draw_width,
-                        3 * _draw_width);
-            }
-            else
-            {
-                /* We found an icon to draw. */
-                gdk_draw_pixbuf(
-                        _map_pixmap,
-                        _gc[COLORABLE_POI],
-                        pixbuf,
-                        0, 0,
-                        poix - gdk_pixbuf_get_width(pixbuf) / 2,
-                        poiy - gdk_pixbuf_get_height(pixbuf) / 2,
-                        -1,-1,
-                        GDK_RGB_DITHER_NONE, 0, 0);
-                g_object_unref(pixbuf);
-            }
-
-            g_free(poi_label);
-            g_free(cat_label);
-        }
-        sqlite3_reset(_stmt_select_poi);
-    }
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static void
-map_render_tile(guint tilex, guint tiley, guint destx, guint desty,
-        gboolean fast_fail)
-{
-    GdkPixbuf *pixbuf = NULL;
-
-    if(tilex < _world_size_tiles && tiley < _world_size_tiles)
-    {
-        /* The tile is possible. */
-        gchar buffer[BUFFER_SIZE];
-        GError *error = NULL;
-        gint zoff;
-        vprintf("%s(%u, %u, %u, %u)\n", __PRETTY_FUNCTION__,
-                tilex, tiley, destx, desty);
-
-        for(zoff = (_curr_repo->double_size ? 1 : 0);
-                !pixbuf && (_zoom + zoff) <= MAX_ZOOM && zoff <= TILE_SIZE_P2;
-                zoff += 1)
-        {
-            snprintf(buffer, sizeof(buffer), "%s/%u/%u/%u.jpg",
-                    _curr_repo->cache_dir,
-                    _zoom + zoff,
-                    (tilex >> zoff),
-                    (tiley >> zoff));
-            pixbuf = gdk_pixbuf_new_from_file(buffer, &error);
-            if(error || !pixbuf)
-            {
-                g_unlink(buffer); /* Delete so we try again some other day. */
-                pixbuf = NULL;
-                error = NULL;
-
-                /* Download, if we should. */
-                if(_auto_download && _curr_repo->type != REPOTYPE_NONE
-                        && !((_zoom + zoff - (_curr_repo->double_size ? 1 : 0))
-                            % _curr_repo->dl_zoom_steps))
-                {
-                    if(!fast_fail)
-                        map_initiate_download(
-                                tilex >> zoff, tiley >> zoff, _zoom + zoff,
-                                -INITIAL_DOWNLOAD_RETRIES);
-                    fast_fail = TRUE;
-                }
-            }
-            else
-            {
-                /* Check if we need to trim. */
-                if(gdk_pixbuf_get_width(pixbuf) != TILE_SIZE_PIXELS
-                        || gdk_pixbuf_get_height(pixbuf) != TILE_SIZE_PIXELS)
-                    pixbuf = pixbuf_trim(pixbuf);
-                /* Check if we need to blit. */
-                if(zoff)
-                    map_pixbuf_scale_inplace(pixbuf, zoff,
-                    (tilex - ((tilex>>zoff) << zoff)) << (TILE_SIZE_P2-zoff),
-                    (tiley - ((tiley>>zoff) << zoff)) << (TILE_SIZE_P2-zoff));
-            }
-        }
-    }
-    if(pixbuf)
-    {
-        gdk_draw_pixbuf(
-                _map_pixmap,
-                _gc[COLORABLE_MARK],
-                pixbuf,
-                0, 0,
-                destx, desty,
-                TILE_SIZE_PIXELS, TILE_SIZE_PIXELS,
-                GDK_RGB_DITHER_NONE, 0, 0);
-        g_object_unref(pixbuf);
-    }
-    else
-    {
-        gdk_draw_rectangle(_map_pixmap, _map_widget->style->black_gc, TRUE,
-                destx, desty,
-                TILE_SIZE_PIXELS, TILE_SIZE_PIXELS);
-    }
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static gboolean
-map_download_idle_refresh(ProgressUpdateInfo *pui)
-{
-    vprintf("%s(%p, %s)\n", __PRETTY_FUNCTION__, pui, pui->src_str);
-
-    /* Test if download succeeded (only if retries != 0). */
-    if(!pui->retries || g_file_test(pui->dest_str, G_FILE_TEST_EXISTS))
-    {
-        gint zoom_diff = pui->zoom - _zoom;
-        /* Only refresh at same or "lower" (more detailed) zoom level. */
-        if(zoom_diff >= 0)
-        {
-            /* If zoom has changed since we first put in the request for
-             * this tile, then we may have to update more than one tile. */
-            guint tilex, tiley, tilex_end, tiley_end;
-            for(tilex = pui->tilex << zoom_diff,
-                    tilex_end = tilex + (1 << zoom_diff);
-                    tilex < tilex_end; tilex++)
-            {
-                for(tiley = pui->tiley<<zoom_diff,
-                        tiley_end = tiley + (1 << zoom_diff);
-                        tiley < tiley_end; tiley++)
-                {
-                    if((tilex-_base_tilex) < 4 && (tiley-_base_tiley) < 3)
-                    {
-                        map_render_tile(
-                                tilex, tiley,
-                                ((tilex - _base_tilex) << TILE_SIZE_P2),
-                                ((tiley - _base_tiley) << TILE_SIZE_P2),
-                                TRUE);
-                        MACRO_MAP_RENDER_DATA();
-                        gtk_widget_queue_draw_area(
-                            _map_widget,
-                            ((tilex-_base_tilex)<<TILE_SIZE_P2) - _offsetx,
-                            ((tiley-_base_tiley)<<TILE_SIZE_P2) - _offsety,
-                            TILE_SIZE_PIXELS, TILE_SIZE_PIXELS);
-                    }
-                }
-            }
-        }
-    }
-    /* Else the download failed. Update retries and maybe try again. */
-    else
-    {
-        if(pui->retries > 0)
-            --pui->retries;
-        else if(pui->retries < 0)
-            ++pui->retries;
-        if(pui->retries)
-        {
-            /* removal automatically calls progress_update_info_free(). */
-            g_tree_steal(_downloading_tree, pui);
-            g_tree_insert(_pui_tree, pui, pui);
-            if(_iap_connected && !_curl_sid)
-                _curl_sid = g_timeout_add(100,
-                        (GSourceFunc)curl_download_timeout, NULL);
-            /* Don't do anything else. */
-            return FALSE;
-        }
-        else
-        {
-            /* No more retries left - something must be wrong. */
-            MACRO_BANNER_SHOW_INFO(_window,
-                    _("Error in download.  Check internet connection"
-                        " and/or Map Repository URL Format."));
-        }
-    }
-
-    /* removal automatically calls progress_update_info_free(). */
-    g_tree_remove(_downloading_tree, pui);
-
-    if(++_curr_download == _num_downloads)
-    {
-        gtk_widget_destroy(_download_banner);
-        _download_banner = NULL;
-        _num_downloads = _curr_download = 0;
-    }
-    else
-        hildon_banner_set_fraction(HILDON_BANNER(_download_banner),
-                _curr_download / (double)_num_downloads);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-    return FALSE;
-}
-
-/**
- * Force a redraw of the entire _map_pixmap, including fetching the
- * background maps from disk and redrawing the tracks on top of them.
- */
-void
-map_force_redraw()
-{
-    guint new_x, new_y;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    for(new_y = 0; new_y < BUF_HEIGHT_TILES; ++new_y)
-        for(new_x = 0; new_x < BUF_WIDTH_TILES; ++new_x)
-        {
-            map_render_tile(
-                    _base_tilex + new_x,
-                    _base_tiley + new_y,
-                    new_x * TILE_SIZE_PIXELS,
-                    new_y * TILE_SIZE_PIXELS,
-                    FALSE);
-        }
-    MACRO_MAP_RENDER_DATA();
-    MACRO_QUEUE_DRAW_AREA();
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static gboolean
-get_next_pui(gpointer key, gpointer value, ProgressUpdateInfo **data)
-{
-    *data = key;
-    return TRUE;
-}
-
-/**
- * Cancel the current auto-route.
- */
-static void
-cancel_autoroute(gboolean temporary)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(_autoroute_data.enabled)
-    {
-        if(!temporary)
-        {
-            _autoroute_data.enabled = FALSE;
-
-            g_free(_autoroute_data.dest);
-            _autoroute_data.dest = NULL;
-
-            g_free(_autoroute_data.src_str);
-            _autoroute_data.src_str = NULL;
-        }
-
-        if(_autoroute_data.curl_easy)
-        {
-            if(_curl_multi)
-                curl_multi_remove_handle(_curl_multi,
-                        _autoroute_data.curl_easy);
-            curl_easy_cleanup(_autoroute_data.curl_easy);
-            _autoroute_data.curl_easy = NULL;
-        }
-
-        g_free(_autoroute_data.rdl_data.bytes);
-        _autoroute_data.rdl_data.bytes = NULL;
-        _autoroute_data.rdl_data.bytes_read = 0;
-
-        _autoroute_data.in_progress = FALSE;
-    }
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static gboolean
-curl_download_timeout()
-{
-    static guint destroy_counter = 50;
-    gint num_transfers = 0, num_msgs = 0;
-    gint deletes_left = 50; /* only do 50 deletes at a time. */
-    CURLMsg *msg;
-    vprintf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(_curl_multi && CURLM_CALL_MULTI_PERFORM
-            == curl_multi_perform(_curl_multi, &num_transfers))
-        return TRUE; /* Give UI a chance first. */
-
-    while(_curl_multi && (msg = curl_multi_info_read(_curl_multi, &num_msgs)))
-    {
-        if(msg->msg == CURLMSG_DONE)
-        {
-            if(msg->easy_handle == _autoroute_data.curl_easy)
-            {
-                /* This is the autoroute download. */
-                /* Now, parse the autoroute and update the display. */
-                if(_autoroute_data.enabled && parse_gpx(&_route,
-                            _autoroute_data.rdl_data.bytes,
-                            _autoroute_data.rdl_data.bytes_read, 0))
-                {
-                    /* Find the nearest route point, if we're connected. */
-                    route_find_nearest_point();
-                    map_force_redraw();
-                }
-                cancel_autoroute(TRUE); /* We're done. Clean up. */
-            }
-            else
-            {
-                ProgressUpdateInfo *pui = g_hash_table_lookup(
-                        _pui_by_easy, msg->easy_handle);
-                g_queue_push_head(_curl_easy_queue, msg->easy_handle);
-                g_hash_table_remove(_pui_by_easy, msg->easy_handle);
-                fclose(pui->file);
-                if(msg->data.result != CURLE_OK)
-                    g_unlink(pui->dest_str); /* Delete so we try again. */
-                curl_multi_remove_handle(_curl_multi, msg->easy_handle);
-                g_idle_add_full(G_PRIORITY_HIGH_IDLE,
-                        (GSourceFunc)map_download_idle_refresh, pui, NULL);
-            }
-        }
-    }
-
-    /* Up to 1 transfer per tile. */
-    while(num_transfers < (BUF_WIDTH_TILES * BUF_HEIGHT_TILES)
-            && g_tree_nnodes(_pui_tree))
-    {
-        ProgressUpdateInfo *pui;
-        g_tree_foreach(_pui_tree, (GTraverseFunc)get_next_pui, &pui);
-
-        if(pui->retries)
-        {
-            /* This is a download. */
-            FILE *f;
-            g_tree_steal(_pui_tree, pui);
-            g_tree_insert(_downloading_tree, pui, pui);
-
-            pui->src_str = map_construct_url(pui->tilex, pui->tiley,pui->zoom);
-            pui->dest_str = g_strdup_printf("%s/%u/%u/%u.jpg",
-                    pui->repo->cache_dir, pui->zoom, pui->tilex, pui->tiley);
-
-            if(!pui->src_str)
-            {
-                /* Failed to generate URL. */
-                g_idle_add_full(G_PRIORITY_HIGH_IDLE,
-                        (GSourceFunc)map_download_idle_refresh, pui, NULL);
-                continue;
-            }
-
-            /* Check to see if we need to overwrite. */
-            if(pui->retries > 0)
-            {
-                /* We're not updating - check if file already exists. */
-                if(g_file_test(pui->dest_str, G_FILE_TEST_EXISTS))
-                {
-                    g_idle_add_full(G_PRIORITY_HIGH_IDLE,
-                            (GSourceFunc)map_download_idle_refresh, pui, NULL);
-                    continue;
-                }
-            }
-
-            /* Attempt to open the file for writing. */
-            if(!(f = g_fopen(pui->dest_str, "w")) && errno == ENOENT)
-            {
-                /* Directory doesn't exist yet - create it, then we'll retry */
-                gchar buffer[BUFFER_SIZE];
-                snprintf(buffer, sizeof(buffer), "%s/%u/%u",
-                        pui->repo->cache_dir, pui->zoom, pui->tilex);
-                g_mkdir_with_parents(buffer, 0775);
-                f = g_fopen(pui->dest_str, "w");
-            }
-
-            if(f)
-            {
-                CURL *curl_easy;
-                pui->file = f;
-                curl_easy = g_queue_pop_tail(_curl_easy_queue);
-                if(!curl_easy)
-                {
-                    /* Need a new curl_easy. */
-                    MACRO_CURL_EASY_INIT(curl_easy);
-                }
-                curl_easy_setopt(curl_easy, CURLOPT_URL, pui->src_str);
-                curl_easy_setopt(curl_easy, CURLOPT_WRITEDATA, f);
-                g_hash_table_insert(_pui_by_easy, curl_easy, pui);
-                if(!_curl_multi)
-                {
-                    /* Initialize CURL. */
-                    _curl_multi = curl_multi_init();
-                    /*curl_multi_setopt(_curl_multi, CURLMOPT_PIPELINING, 1);*/
-                }
-                curl_multi_add_handle(_curl_multi, curl_easy);
-                num_transfers++;
-            }
-            else
-            {
-                /* Unable to download file. */
-                gchar buffer[BUFFER_SIZE];
-                snprintf(buffer, sizeof(buffer), "%s:\n%s",
-                        _("Failed to open file for writing"), pui->dest_str);
-                MACRO_BANNER_SHOW_INFO(_window, buffer);
-                g_idle_add_full(G_PRIORITY_HIGH_IDLE,
-                        (GSourceFunc)map_download_idle_refresh, pui, NULL);
-                continue;
-            }
-        }
-        else if(--deletes_left)
-        {
-            /* This is a delete. */
-            gchar buffer[BUFFER_SIZE];
-            g_tree_steal(_pui_tree, pui);
-            g_tree_insert(_downloading_tree, pui, pui);
-
-            snprintf(buffer, sizeof(buffer), "%s/%u/%u/%u.jpg",
-                    pui->repo->cache_dir, pui->zoom, pui->tilex, pui->tiley);
-            g_unlink(buffer);
-            g_idle_add_full(G_PRIORITY_HIGH_IDLE,
-                    (GSourceFunc)map_download_idle_refresh, pui, NULL);
-        }
-        else
-            break;
-    }
-
-    if(!(num_transfers || g_tree_nnodes(_pui_tree)))
-    {
-        /* Destroy curl after 50 counts (5 seconds). */
-        if(--destroy_counter)
-        {
-            /* Clean up curl. */
-            CURL *curr;
-            while((curr = g_queue_pop_tail(_curl_easy_queue)))
-                curl_easy_cleanup(curr);
-
-            curl_multi_cleanup(_curl_multi);
-            _curl_multi = NULL;
-
-            _curl_sid = 0;
-            vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
-            return FALSE;
-        }
-    }
-    else
-        destroy_counter = 50;
-
-    vprintf("%s(): return TRUE (%d, %d)\n", __PRETTY_FUNCTION__,
-            num_transfers, g_tree_nnodes(_pui_tree));
-    return TRUE;
-}
-
-/**
- * Set the current zoom level.  If the given zoom level is the same as the
- * current zoom level, or if the new zoom is invalid
- * (not MIN_ZOOM <= new_zoom < MAX_ZOOM), then this method does nothing.
- */
-void
-map_set_zoom(guint new_zoom)
-{
-    printf("%s(%d)\n", __PRETTY_FUNCTION__, _zoom);
-
-    /* Note that, since new_zoom is a guint and MIN_ZOOM is 0, this if
-     * condition also checks for new_zoom >= MIN_ZOOM. */
-    if(new_zoom > (MAX_ZOOM - 1))
-        return;
-    _zoom = new_zoom / _curr_repo->view_zoom_steps
-                     * _curr_repo->view_zoom_steps;
-    _world_size_tiles = unit2tile(WORLD_SIZE_UNITS);
-
-    /* If we're leading, update the center to reflect new zoom level. */
-    MACRO_RECALC_CENTER(_center.unitx, _center.unity);
-
-    /* Update center bounds to reflect new zoom level. */
-    _min_center.unitx = pixel2unit(grid2pixel(_screen_grids_halfwidth));
-    _min_center.unity = pixel2unit(grid2pixel(_screen_grids_halfheight));
-    _max_center.unitx = WORLD_SIZE_UNITS-grid2unit(_screen_grids_halfwidth) -1;
-    _max_center.unity = WORLD_SIZE_UNITS-grid2unit(_screen_grids_halfheight)-1;
-
-    BOUND(_center.unitx, _min_center.unitx, _max_center.unitx);
-    BOUND(_center.unity, _min_center.unity, _max_center.unity);
-
-    _base_tilex = grid2tile((gint)pixel2grid(
-                (gint)unit2pixel((gint)_center.unitx))
-            - (gint)_screen_grids_halfwidth);
-    _base_tiley = grid2tile(pixel2grid(
-                unit2pixel(_center.unity))
-            - _screen_grids_halfheight);
-
-    /* New zoom level, so we can't reuse the old buffer's pixels. */
-
-
-    /* Update state variables. */
-    MACRO_RECALC_OFFSET();
-    MACRO_RECALC_FOCUS_BASE();
-    MACRO_RECALC_FOCUS_SIZE();
-
-    map_set_mark();
-    map_force_redraw();
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-/**
- * Center the view on the given unitx/unity.
- */
-static void
-map_center_unit(guint new_center_unitx, guint new_center_unity)
-{
-    gint new_base_tilex, new_base_tiley;
-    guint new_x, new_y;
-    guint j, k, base_new_x, base_old_x, old_x, old_y, iox, ioy;
-    printf("%s(%d, %d)\n", __PRETTY_FUNCTION__,
-            new_center_unitx, new_center_unity);
-
-    /* Assure that _center.unitx/y are bounded. */
-    BOUND(new_center_unitx, _min_center.unitx, _max_center.unitx);
-    BOUND(new_center_unity, _min_center.unity, _max_center.unity);
-
-    _center.unitx = new_center_unitx;
-    _center.unity = new_center_unity;
-
-    new_base_tilex = grid2tile((gint)pixel2grid(
-                (gint)unit2pixel((gint)_center.unitx))
-            - (gint)_screen_grids_halfwidth);
-    new_base_tiley = grid2tile(pixel2grid(
-                unit2pixel(_center.unity))
-            - _screen_grids_halfheight);
-
-    /* Same zoom level, so it's likely that we can reuse some of the old
-     * buffer's pixels. */
-
-    if(new_base_tilex != _base_tilex
-            || new_base_tiley != _base_tiley)
-    {
-        /* If copying from old parts to new parts, we need to make sure we
-         * don't overwrite the old parts when copying, so set up new_x,
-         * new_y, old_x, old_y, iox, and ioy with that in mind. */
-        if(new_base_tiley < _base_tiley)
-        {
-            /* New is lower than old - start at bottom and go up. */
-            new_y = BUF_HEIGHT_TILES - 1;
-            ioy = -1;
-        }
-        else
-        {
-            /* New is higher than old - start at top and go down. */
-            new_y = 0;
-            ioy = 1;
-        }
-        if(new_base_tilex < _base_tilex)
-        {
-            /* New is righter than old - start at right and go left. */
-            base_new_x = BUF_WIDTH_TILES - 1;
-            iox = -1;
-        }
-        else
-        {
-            /* New is lefter than old - start at left and go right. */
-            base_new_x = 0;
-            iox = 1;
-        }
-
-        /* Iterate over the y tile values. */
-        old_y = new_y + new_base_tiley - _base_tiley;
-        base_old_x = base_new_x + new_base_tilex - _base_tilex;
-        _base_tilex = new_base_tilex;
-        _base_tiley = new_base_tiley;
-        for(j = 0; j < BUF_HEIGHT_TILES; ++j, new_y += ioy, old_y += ioy)
-        {
-            new_x = base_new_x;
-            old_x = base_old_x;
-            /* Iterate over the x tile values. */
-            for(k = 0; k < BUF_WIDTH_TILES; ++k, new_x += iox, old_x += iox)
-            {
-                /* Can we get this grid block from the old buffer?. */
-                if(old_x >= 0 && old_x < BUF_WIDTH_TILES
-                        && old_y >= 0 && old_y < BUF_HEIGHT_TILES)
-                {
-                    /* Copy from old buffer to new buffer. */
-                    gdk_draw_drawable(
-                            _map_pixmap,
-                            _gc[COLORABLE_MARK],
-                            _map_pixmap,
-                            old_x * TILE_SIZE_PIXELS,
-                            old_y * TILE_SIZE_PIXELS,
-                            new_x * TILE_SIZE_PIXELS,
-                            new_y * TILE_SIZE_PIXELS,
-                            TILE_SIZE_PIXELS, TILE_SIZE_PIXELS);
-                }
-                else
-                {
-                    map_render_tile(
-                            new_base_tilex + new_x,
-                            new_base_tiley + new_y,
-                            new_x * TILE_SIZE_PIXELS,
-                            new_y * TILE_SIZE_PIXELS,
-                            FALSE);
-                }
-            }
-        }
-        MACRO_RECALC_OFFSET();
-        MACRO_RECALC_FOCUS_BASE();
-        MACRO_MAP_RENDER_DATA();
-    }
-    else
-    {
-        MACRO_RECALC_OFFSET();
-        MACRO_RECALC_FOCUS_BASE();
-    }
-
-    map_set_mark();
-    MACRO_QUEUE_DRAW_AREA();
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-/**
- * Pan the view by the given number of units in the X and Y directions.
- */
-void
-map_pan(gint delta_unitx, gint delta_unity)
-{
-    printf("%s(%d, %d)\n", __PRETTY_FUNCTION__, delta_unitx, delta_unity);
-
-    if(_center_mode > 0)
-        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(
-                    _menu_ac_none_item), TRUE);
-    map_center_unit(
-            _center.unitx + delta_unitx,
-            _center.unity + delta_unity);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-/**
- * Initiate a move of the mark from the old location to the current
- * location.  This function queues the draw area of the old mark (to force
- * drawing of the background map), then updates the mark, then queus the
- * draw area of the new mark.
- */
-static void
-map_move_mark()
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    /* Just queue the old and new draw areas. */
-    gtk_widget_queue_draw_area(_map_widget,
-            _mark_minx,
-            _mark_miny,
-            _mark_width,
-            _mark_height);
-    map_set_mark();
-    gtk_widget_queue_draw_area(_map_widget,
-            _mark_minx,
-            _mark_miny,
-            _mark_width,
-            _mark_height);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-/**
- * Make sure the mark is up-to-date.  This function triggers a panning of
- * the view if the mark is appropriately close to the edge of the view.
- */
-static void
-refresh_mark()
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    guint new_center_unitx;
-    guint new_center_unity;
-
-    MACRO_RECALC_CENTER(new_center_unitx, new_center_unity);
-
-    if((new_center_unitx - _focus.unitx) < _focus_unitwidth
-            && (new_center_unity - _focus.unity) < _focus_unitheight)
-        /* We're not changing the view - just move the mark. */
-        map_move_mark();
-    else
-        map_center_unit(new_center_unitx, new_center_unity);
-
-    /* Draw speed info */
-    if(_speed_limit_on)
-        speed_limit();
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-/**
- * This is a multi-purpose function for allowing the user to select a file
- * for either reading or writing.  If chooser_action is
- * GTK_FILE_CHOOSER_ACTION_OPEN, then bytes_out and size_out must be
- * non-NULL.  If chooser_action is GTK_FILE_CHOOSER_ACTION_SAVE, then
- * handle_out must be non-NULL.  Either dir or file (or both) can be NULL.
- * This function returns TRUE if a file was successfully opened.
- */
-static gboolean
-open_file(gchar **bytes_out, GnomeVFSHandle **handle_out, gint *size_out,
-        gchar **dir, gchar **file, GtkFileChooserAction chooser_action)
-{
-    GtkWidget *dialog;
-    gboolean success = FALSE;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    dialog= hildon_file_chooser_dialog_new(GTK_WINDOW(_window),chooser_action);
-
-    if(dir && *dir)
-        gtk_file_chooser_set_current_folder_uri(
-                GTK_FILE_CHOOSER(dialog), *dir);
-    if(file && *file)
-    {
-        GValue val;
-        gtk_file_chooser_set_uri(
-                GTK_FILE_CHOOSER(dialog), *file);
-        if(chooser_action == GTK_FILE_CHOOSER_ACTION_SAVE)
-        {
-            /* Work around a bug in HildonFileChooserDialog. */
-            memset(&val, 0, sizeof(val));
-            g_value_init(&val, G_TYPE_BOOLEAN);
-            g_value_set_boolean(&val, FALSE);
-            g_object_set_property(G_OBJECT(dialog), "autonaming", &val);
-            gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog),
-                    strrchr(*file, '/') + 1);
-        }
-    }
-
-    gtk_widget_show_all(dialog);
-
-    while(!success && gtk_dialog_run(GTK_DIALOG(dialog))==GTK_RESPONSE_OK)
-    {
-        gchar *file_uri_str;
-        GnomeVFSResult vfs_result;
-
-        /* Get the selected filename. */
-        file_uri_str = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(dialog));
-
-        if((chooser_action == GTK_FILE_CHOOSER_ACTION_OPEN
-                && (GNOME_VFS_OK != (vfs_result = gnome_vfs_read_entire_file(
-                        file_uri_str, size_out, bytes_out))))
-                || (chooser_action == GTK_FILE_CHOOSER_ACTION_SAVE
-                    && GNOME_VFS_OK != (vfs_result = gnome_vfs_create(
-                            handle_out, file_uri_str,
-                            GNOME_VFS_OPEN_WRITE, FALSE, 0664))))
-        {
-            gchar buffer[BUFFER_SIZE];
-            snprintf(buffer, sizeof(buffer),
-                    "%s:\n%s", chooser_action == GTK_FILE_CHOOSER_ACTION_OPEN
-                                ? _("Failed to open file for reading")
-                                : _("Failed to open file for writing"),
-                    gnome_vfs_result_to_string(vfs_result));
-            popup_error(dialog, buffer);
-        }
-        else
-            success = TRUE;
-
-        g_free(file_uri_str);
-    }
-
-    if(success)
-    {
-        /* Success!. */
-        if(dir)
-        {
-            g_free(*dir);
-            *dir = gtk_file_chooser_get_current_folder_uri(
-                    GTK_FILE_CHOOSER(dialog));
-        }
-
-        /* If desired, save the file for later. */
-        if(file)
-        {
-            g_free(*file);
-            *file = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(dialog));
-        }
-    }
-
-    gtk_widget_destroy(dialog);
-
-    vprintf("%s(): return %d\n", __PRETTY_FUNCTION__, success);
-    return success;
-}
-
-/**
- * Read the data provided by the given handle as GPX data, updating the
- * auto-route with that data.
- */
-static size_t
-route_dl_cb_read(void *ptr, size_t size, size_t nmemb,
-        RouteDownloadData *rdl_data)
-{
-    size_t old_size = rdl_data->bytes_read;
-    vprintf("%s()\n", __PRETTY_FUNCTION__);
-
-    rdl_data->bytes_read += size * nmemb;
-    rdl_data->bytes = g_renew(gchar, rdl_data->bytes,
-            rdl_data->bytes_read);
-    g_memmove(rdl_data->bytes + old_size, ptr, size * nmemb);
-
-    vprintf("%s(): return %d\n", __PRETTY_FUNCTION__, size * nmemb);
-    return (size * nmemb);
-}
-
-/**
- * This function is periodically run to download updated auto-route data
- * from the route source.
- */
-static gboolean
-auto_route_dl_idle()
-{
-    gchar latstr[32], lonstr[32], *latlonstr;
-    printf("%s(%f, %f, %s)\n", __PRETTY_FUNCTION__,
-            _gps.lat, _gps.lon, _autoroute_data.dest);
-
-    g_ascii_dtostr(latstr, 32, _gps.lat);
-    g_ascii_dtostr(lonstr, 32, _gps.lon);
-    latlonstr = g_strdup_printf("%s,%s", latstr, lonstr);
-    _autoroute_data.src_str = g_strdup_printf(
-            _route_dl_url, latlonstr, _autoroute_data.dest);
-    g_free(latlonstr);
-
-    MACRO_CURL_EASY_INIT(_autoroute_data.curl_easy);
-    curl_easy_setopt(_autoroute_data.curl_easy, CURLOPT_URL,
-            _autoroute_data.src_str);
-    curl_easy_setopt(_autoroute_data.curl_easy, CURLOPT_WRITEFUNCTION,
-            route_dl_cb_read);
-    curl_easy_setopt(_autoroute_data.curl_easy, CURLOPT_WRITEDATA,
-            &_autoroute_data.rdl_data);
-    if(!_curl_multi)
-    {
-        /* Initialize CURL. */
-        _curl_multi = curl_multi_init();
-        /*curl_multi_setopt(_curl_multi, CURLMOPT_PIPELINING, 1);*/
-    }
-    curl_multi_add_handle(_curl_multi, _autoroute_data.curl_easy);
-    if(_iap_connected && !_curl_sid)
-        _curl_sid = g_timeout_add(100,
-                (GSourceFunc)curl_download_timeout, NULL);
-    _autoroute_data.in_progress = TRUE;
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-    return FALSE;
-}
-
-/**
- * Save state and destroy all non-UI elements created by this program in
- * preparation for exiting.
- */
-static void
-maemo_mapper_destroy(void)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(_curl_sid)
-    {
-        g_source_remove(_curl_sid);
-        _curl_sid = 0;
-    }
-    config_save();
-    rcvr_disconnect();
-    /* _program and widgets have already been destroyed. */
-
-    if(_db)
-    {
-        sqlite3_close(_db);
-        _db = NULL;
-    }
-
-    MACRO_PATH_FREE(_track);
-    MACRO_PATH_FREE(_route);
-
-    /* Clean up CURL. */
-    if(_curl_multi)
-    {
-        CURL *curr;
-        CURLMsg *msg;
-        gint num_transfers, num_msgs;
-
-        /* First, remove all downloads from _pui_tree. */
-        g_tree_destroy(_pui_tree);
-
-        /* Finish up all downloads. */
-        while(CURLM_CALL_MULTI_PERFORM
-                == curl_multi_perform(_curl_multi, &num_transfers)
-                || num_transfers) { }
-
-        /* Close all finished files. */
-        while((msg = curl_multi_info_read(_curl_multi, &num_msgs)))
-        {
-            if(msg->msg == CURLMSG_DONE)
-            {
-                /* This is a map download. */
-                ProgressUpdateInfo *pui = g_hash_table_lookup(
-                        _pui_by_easy, msg->easy_handle);
-                g_queue_push_head(_curl_easy_queue, msg->easy_handle);
-                g_hash_table_remove(_pui_by_easy, msg->easy_handle);
-                fclose(pui->file);
-                curl_multi_remove_handle(_curl_multi, msg->easy_handle);
-            }
-        }
-
-        while((curr = g_queue_pop_tail(_curl_easy_queue)))
-            curl_easy_cleanup(curr);
-
-        curl_multi_cleanup(_curl_multi);
-        _curl_multi = NULL;
-
-        g_queue_free(_curl_easy_queue);
-        g_tree_destroy(_downloading_tree);
-        g_hash_table_destroy(_pui_by_easy);
-    }
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static DBusHandlerResult
-get_connection_status_signal_cb(DBusConnection *connection,
-        DBusMessage *message, void *user_data)
-{
-    gchar *iap_name = NULL, *iap_nw_type = NULL, *iap_state = NULL;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    /* check signal */
-    if(!dbus_message_is_signal(message,
-                ICD_DBUS_INTERFACE,
-                ICD_STATUS_CHANGED_SIG))
-    {
-        vprintf("%s(): return DBUS_HANDLER_RESULT_NOT_YET_HANDLED\n",
-                __PRETTY_FUNCTION__);
-        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-    }
-
-    if(!dbus_message_get_args(message, NULL,
-                DBUS_TYPE_STRING, &iap_name,
-                DBUS_TYPE_STRING, &iap_nw_type,
-                DBUS_TYPE_STRING, &iap_state,
-                DBUS_TYPE_INVALID))
-    {
-        vprintf("%s(): return DBUS_HANDLER_RESULT_NOT_YET_HANDLED\n",
-                __PRETTY_FUNCTION__);
-        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-    }
-
-    printf("  > iap_state = %s\n", iap_state);
-    if(!strcmp(iap_state, "CONNECTED"))
-    {
-        if(!_iap_connected)
-        {
-            _iap_connected = TRUE;
-            config_update_proxy();
-            if(!_curl_sid)
-                _curl_sid = g_timeout_add(100,
-                        (GSourceFunc)curl_download_timeout, NULL);
-        }
-    }
-    else if(_iap_connected)
-    {
-        _iap_connected = FALSE;
-        if(_curl_sid)
-        {
-            g_source_remove(_curl_sid);
-            _curl_sid = 0;
-        }
-    }
-
-    vprintf("%s(): return DBUS_HANDLER_RESULT_HANDLED\n",
-            __PRETTY_FUNCTION__);
-    return DBUS_HANDLER_RESULT_HANDLED;
-}
-
-static void
-iap_callback(struct iap_event_t *event, void *arg)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-    _iap_connecting = FALSE;
-    if(event->type == OSSO_IAP_CONNECTED && !_iap_connected)
-    {
-        _iap_connected = TRUE;
-        config_update_proxy();
-        if(!_curl_sid)
-            _curl_sid = g_timeout_add(100,
-                    (GSourceFunc)curl_download_timeout, NULL);
-    }
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-/**
- * Initialize everything required in preparation for calling gtk_main().
- */
-static void
-maemo_mapper_init(gint argc, gchar **argv)
-{
-    GtkWidget *hbox, *label, *vbox;
-    GdkColor color;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    /* Set enum-based constants. */
-    UNITS_TEXT[UNITS_KM] = _("km");
-    UNITS_TEXT[UNITS_MI] = _("mi.");
-    UNITS_TEXT[UNITS_NM] = _("n.m.");
-
-    INFO_FONT_TEXT[INFO_FONT_XXSMALL] = "xx-small";
-    INFO_FONT_TEXT[INFO_FONT_XSMALL] = "x-small";
-    INFO_FONT_TEXT[INFO_FONT_SMALL] = "small";
-    INFO_FONT_TEXT[INFO_FONT_MEDIUM] = "medium";
-    INFO_FONT_TEXT[INFO_FONT_LARGE] = "large";
-    INFO_FONT_TEXT[INFO_FONT_XLARGE] = "x-large";
-    INFO_FONT_TEXT[INFO_FONT_XXLARGE] = "xx-large";
-
-    CUSTOM_KEY_GCONF[CUSTOM_KEY_UP] = GCONF_KEY_PREFIX"/key_up";
-    CUSTOM_KEY_GCONF[CUSTOM_KEY_DOWN] = GCONF_KEY_PREFIX"/key_down";
-    CUSTOM_KEY_GCONF[CUSTOM_KEY_LEFT] = GCONF_KEY_PREFIX"/key_left";
-    CUSTOM_KEY_GCONF[CUSTOM_KEY_RIGHT] = GCONF_KEY_PREFIX"/key_right";
-    CUSTOM_KEY_GCONF[CUSTOM_KEY_SELECT] = GCONF_KEY_PREFIX"/key_select";
-    CUSTOM_KEY_GCONF[CUSTOM_KEY_INCREASE] = GCONF_KEY_PREFIX"/key_increase";
-    CUSTOM_KEY_GCONF[CUSTOM_KEY_DECREASE] = GCONF_KEY_PREFIX"/key_decrease";
-    CUSTOM_KEY_GCONF[CUSTOM_KEY_FULLSCREEN]= GCONF_KEY_PREFIX"/key_fullscreen";
-    CUSTOM_KEY_GCONF[CUSTOM_KEY_ESC] = GCONF_KEY_PREFIX"/key_esc";
-
-    CUSTOM_KEY_ICON[CUSTOM_KEY_UP] = HWK_BUTTON_UP;
-    CUSTOM_KEY_ICON[CUSTOM_KEY_LEFT] = HWK_BUTTON_LEFT;
-    CUSTOM_KEY_ICON[CUSTOM_KEY_DOWN] = HWK_BUTTON_DOWN;
-    CUSTOM_KEY_ICON[CUSTOM_KEY_RIGHT] = HWK_BUTTON_RIGHT;
-    CUSTOM_KEY_ICON[CUSTOM_KEY_SELECT] = HWK_BUTTON_SELECT;
-    CUSTOM_KEY_ICON[CUSTOM_KEY_INCREASE] = HWK_BUTTON_INCREASE;
-    CUSTOM_KEY_ICON[CUSTOM_KEY_DECREASE] = HWK_BUTTON_DECREASE;
-    CUSTOM_KEY_ICON[CUSTOM_KEY_FULLSCREEN] = HWK_BUTTON_VIEW;
-    CUSTOM_KEY_ICON[CUSTOM_KEY_ESC] = HWK_BUTTON_CANCEL;
-
-    CUSTOM_KEY_DEFAULT[CUSTOM_KEY_UP] = CUSTOM_ACTION_PAN_NORTH;
-    CUSTOM_KEY_DEFAULT[CUSTOM_KEY_LEFT] = CUSTOM_ACTION_PAN_WEST;
-    CUSTOM_KEY_DEFAULT[CUSTOM_KEY_DOWN] = CUSTOM_ACTION_PAN_SOUTH;
-    CUSTOM_KEY_DEFAULT[CUSTOM_KEY_RIGHT] = CUSTOM_ACTION_PAN_EAST;
-    CUSTOM_KEY_DEFAULT[CUSTOM_KEY_SELECT] = CUSTOM_ACTION_TOGGLE_AUTOCENTER;
-    CUSTOM_KEY_DEFAULT[CUSTOM_KEY_INCREASE] = CUSTOM_ACTION_ZOOM_IN;
-    CUSTOM_KEY_DEFAULT[CUSTOM_KEY_DECREASE] = CUSTOM_ACTION_ZOOM_OUT;
-    CUSTOM_KEY_DEFAULT[CUSTOM_KEY_FULLSCREEN]= CUSTOM_ACTION_TOGGLE_FULLSCREEN;
-    CUSTOM_KEY_DEFAULT[CUSTOM_KEY_ESC] = CUSTOM_ACTION_TOGGLE_TRACKS;
-
-    CUSTOM_ACTION_TEXT[CUSTOM_ACTION_PAN_NORTH] = _("Pan North");
-    CUSTOM_ACTION_TEXT[CUSTOM_ACTION_PAN_WEST] = _("Pan West");
-    CUSTOM_ACTION_TEXT[CUSTOM_ACTION_PAN_SOUTH] = _("Pan South");
-    CUSTOM_ACTION_TEXT[CUSTOM_ACTION_PAN_EAST] = _("Pan East");
-    CUSTOM_ACTION_TEXT[CUSTOM_ACTION_TOGGLE_AUTOCENTER]
-        = _("Toggle Auto-Center");
-    CUSTOM_ACTION_TEXT[CUSTOM_ACTION_TOGGLE_FULLSCREEN]
-        = _("Toggle Fullscreen");
-    CUSTOM_ACTION_TEXT[CUSTOM_ACTION_ZOOM_IN] = _("Zoom In");
-    CUSTOM_ACTION_TEXT[CUSTOM_ACTION_ZOOM_OUT] = _("Zoom Out");
-    CUSTOM_ACTION_TEXT[CUSTOM_ACTION_TOGGLE_TRACKS] = _("Toggle Tracks");
-    CUSTOM_ACTION_TEXT[CUSTOM_ACTION_TOGGLE_SCALE] = _("Toggle Scale");
-    CUSTOM_ACTION_TEXT[CUSTOM_ACTION_TOGGLE_POI] = _("Toggle POIs");
-    CUSTOM_ACTION_TEXT[CUSTOM_ACTION_CHANGE_REPO]= _("Select Next Repository");
-    CUSTOM_ACTION_TEXT[CUSTOM_ACTION_ROUTE_DISTNEXT]
-        = _("Show Distance to Next Waypoint");
-    CUSTOM_ACTION_TEXT[CUSTOM_ACTION_ROUTE_DISTLAST]
-        = _("Show Distance to End of Route");
-    CUSTOM_ACTION_TEXT[CUSTOM_ACTION_TRACK_BREAK] = _("Insert Track Break");
-    CUSTOM_ACTION_TEXT[CUSTOM_ACTION_TRACK_CLEAR] = _("Clear Track");
-    CUSTOM_ACTION_TEXT[CUSTOM_ACTION_TRACK_DISTLAST]
-        = _("Show Distance from Last Break");
-    CUSTOM_ACTION_TEXT[CUSTOM_ACTION_TRACK_DISTFIRST]
-        = _("Show Distance from Beginning");
-    CUSTOM_ACTION_TEXT[CUSTOM_ACTION_TOGGLE_GPS] = _("Toggle GPS");
-    CUSTOM_ACTION_TEXT[CUSTOM_ACTION_TOGGLE_GPSINFO] = _("Toggle GPS Info");
-    CUSTOM_ACTION_TEXT[CUSTOM_ACTION_TOGGLE_SPEEDLIMIT]
-        = _("Toggle Speed Limit");
-    CUSTOM_ACTION_TEXT[CUSTOM_ACTION_RESET_BLUETOOTH] = _("Reset Bluetooth");
-
-    COLORABLE_GCONF[COLORABLE_MARK] = GCONF_KEY_PREFIX"/color_mark";
-    COLORABLE_GCONF[COLORABLE_MARK_VELOCITY]
-        = GCONF_KEY_PREFIX"/color_mark_velocity";
-    COLORABLE_GCONF[COLORABLE_MARK_OLD] = GCONF_KEY_PREFIX"/color_mark_old";
-    COLORABLE_GCONF[COLORABLE_TRACK] = GCONF_KEY_PREFIX"/color_track";
-    COLORABLE_GCONF[COLORABLE_TRACK_MARK] =GCONF_KEY_PREFIX"/color_track_mark";
-    COLORABLE_GCONF[COLORABLE_TRACK_BREAK]
-        = GCONF_KEY_PREFIX"/color_track_break";
-    COLORABLE_GCONF[COLORABLE_ROUTE] = GCONF_KEY_PREFIX"/color_route";
-    COLORABLE_GCONF[COLORABLE_ROUTE_WAY] = GCONF_KEY_PREFIX"/color_route_way";
-    COLORABLE_GCONF[COLORABLE_ROUTE_BREAK]
-        = GCONF_KEY_PREFIX"/color_route_break";
-    COLORABLE_GCONF[COLORABLE_POI] = GCONF_KEY_PREFIX"/color_poi";
-
-    DEG_FORMAT_TEXT[DDPDDDDD] = "-dd.ddddd°";
-    DEG_FORMAT_TEXT[DD_MMPMMM] = "-dd°mm.mmm'";
-    DEG_FORMAT_TEXT[DD_MM_SSPS] = "-dd°mm'ss.s\"";
-    DEG_FORMAT_TEXT[DDPDDDDD_NSEW] = "dd.ddddd° S";
-    DEG_FORMAT_TEXT[DD_MMPMMM_NSEW] = "dd°mm.mmm' S";
-    DEG_FORMAT_TEXT[DD_MM_SSPS_NSEW] = "dd°mm'ss.s\" S";
-    DEG_FORMAT_TEXT[NSEW_DDPDDDDD] = "S dd.ddddd°";
-    DEG_FORMAT_TEXT[NSEW_DD_MMPMMM] = "S dd° mm.mmm'";
-    DEG_FORMAT_TEXT[NSEW_DD_MM_SSPS] = "S dd° mm' ss.s\"";
-
-    SPEED_LOCATION_TEXT[SPEED_LOCATION_TOP_LEFT] = _("Top-Left");
-    SPEED_LOCATION_TEXT[SPEED_LOCATION_TOP_RIGHT] = _("Top-Right");
-    SPEED_LOCATION_TEXT[SPEED_LOCATION_BOTTOM_RIGHT] = _("Bottom-Right");
-    SPEED_LOCATION_TEXT[SPEED_LOCATION_BOTTOM_LEFT] = _("Bottom-Left");
-
-    /* Set up track array (must be done before config). */
-    memset(&_track, 0, sizeof(_track));
-    memset(&_route, 0, sizeof(_route));
-    MACRO_PATH_INIT(_track);
-    MACRO_PATH_INIT(_route);
-
-    config_init();
-
-    /* Initialize _program. */
-    _program = HILDON_PROGRAM(hildon_program_get_instance());
-    g_set_application_name("Maemo Mapper");
-
-    /* Initialize _window. */
-    _window = GTK_WIDGET(hildon_window_new());
-    hildon_program_add_window(_program, HILDON_WINDOW(_window));
-
-    /* Lets go fullscreen if so requested in saved config */
-    if (_fullscreen) {
-      gtk_window_fullscreen(GTK_WINDOW(_window));
-    }
-
-    /* Create and add widgets and supporting data. */
-    hbox = gtk_hbox_new(FALSE, 0);
-    gtk_container_add(GTK_CONTAINER(_window), hbox);
-
-    _gps_widget = gtk_frame_new("GPS Info");
-    gtk_container_add(GTK_CONTAINER(_gps_widget),
-            vbox = gtk_vbox_new(FALSE, 0));
-    gtk_widget_set_size_request(GTK_WIDGET(_gps_widget), 180, 0);
-    gtk_box_pack_start(GTK_BOX(hbox), _gps_widget, FALSE, TRUE, 0);
-
-    label = gtk_label_new(" ");
-    gtk_widget_set_size_request(GTK_WIDGET(label), -1, 10);
-    gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 0);
-
-    _text_lat = gtk_label_new(" --- ");
-    gtk_widget_set_size_request(GTK_WIDGET(_text_lat), -1, 30);
-    gtk_box_pack_start(GTK_BOX(vbox), _text_lat, FALSE, TRUE, 0);
-
-    _text_lon = gtk_label_new(" --- ");
-    gtk_widget_set_size_request(GTK_WIDGET(_text_lon), -1, 30);
-    gtk_box_pack_start(GTK_BOX(vbox), _text_lon, FALSE, TRUE, 0);
-
-    _text_speed = gtk_label_new(" --- ");
-    gtk_widget_set_size_request(GTK_WIDGET(_text_speed), -1, 30);
-    gtk_box_pack_start(GTK_BOX(vbox), _text_speed, FALSE, TRUE, 0);
-
-    _text_alt = gtk_label_new(" --- ");
-    gtk_widget_set_size_request(GTK_WIDGET(_text_alt), -1, 30);
-    gtk_box_pack_start(GTK_BOX(vbox), _text_alt, FALSE, TRUE, 0);
-
-    label = gtk_label_new(" ");
-    gtk_widget_set_size_request(GTK_WIDGET(label), -1, 10);
-    gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 0);
-
-    _sat_panel = gtk_drawing_area_new ();
-    gtk_widget_set_size_request (_sat_panel, -1, 100);
-    gtk_box_pack_start(GTK_BOX(vbox), _sat_panel, TRUE, TRUE, 0);
-
-    label = gtk_label_new(" ");
-    gtk_widget_set_size_request(GTK_WIDGET(label), -1, 10);
-    gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 0);
-
-    _text_time = gtk_label_new("--:--:--");
-    gtk_widget_set_size_request(GTK_WIDGET(_text_time), -1, 30);
-    gtk_box_pack_start(GTK_BOX(vbox), _text_time, FALSE, TRUE, 0);
-
-    _heading_panel = gtk_drawing_area_new ();
-    gtk_widget_set_size_request (_heading_panel, -1, 100);
-    gtk_box_pack_start(GTK_BOX(vbox), _heading_panel, TRUE, TRUE, 0);
-
-    _map_widget = gtk_drawing_area_new();
-    gtk_box_pack_start(GTK_BOX(hbox), _map_widget, TRUE, TRUE, 0);
-
-    gtk_widget_show_all(hbox);
-    gps_show_info(); /* hides info, if necessary. */
-
-    gtk_widget_realize(_map_widget);
-
-    _map_pixmap = gdk_pixmap_new(
-                _map_widget->window,
-                BUF_WIDTH_PIXELS, BUF_HEIGHT_PIXELS,
-                -1); /* -1: use bit depth of widget->window. */
-
-    _curl_easy_queue = g_queue_new();
-
-    _pui_tree = g_tree_new_full(
-            (GCompareDataFunc)download_comparefunc, NULL,
-            (GDestroyNotify)progress_update_info_free, NULL);
-    _downloading_tree = g_tree_new_full(
-            (GCompareDataFunc)download_comparefunc, NULL,
-            (GDestroyNotify)progress_update_info_free, NULL);
-
-    _pui_by_easy = g_hash_table_new(g_direct_hash, g_direct_equal);
-
-    /* Connect signals. */
-    g_signal_connect(G_OBJECT(_sat_panel), "expose_event",
-            G_CALLBACK(sat_panel_expose), NULL);
-    g_signal_connect(G_OBJECT(_heading_panel), "expose_event",
-            G_CALLBACK(heading_panel_expose), NULL);
-    g_signal_connect(G_OBJECT(_window), "destroy",
-            G_CALLBACK(gtk_main_quit), NULL);
-
-    g_signal_connect(G_OBJECT(_window), "key_press_event",
-            G_CALLBACK(window_cb_key_press), NULL);
-
-    g_signal_connect(G_OBJECT(_window), "key_release_event",
-            G_CALLBACK(window_cb_key_release), NULL);
-
-    g_signal_connect(G_OBJECT(_map_widget), "configure_event",
-            G_CALLBACK(map_cb_configure), NULL);
-
-    g_signal_connect(G_OBJECT(_map_widget), "expose_event",
-            G_CALLBACK(map_cb_expose), NULL);
-
-    g_signal_connect(G_OBJECT(_map_widget), "button_press_event",
-            G_CALLBACK(map_cb_button_press), NULL);
-
-    g_signal_connect(G_OBJECT(_map_widget), "button_release_event",
-            G_CALLBACK(map_cb_button_release), NULL);
-
-    gtk_widget_add_events(_map_widget,
-            GDK_EXPOSURE_MASK
-            | GDK_BUTTON_PRESS_MASK
-            | GDK_BUTTON_RELEASE_MASK);
-
-    osso_hw_set_event_cb(_osso, NULL, osso_cb_hw_state, NULL);
-
-    /* Initialize data. */
-
-    /* Cache some pango and GCs for drawing. */
-    _scale_context = gtk_widget_get_pango_context(_map_widget);
-    _scale_layout = pango_layout_new(_scale_context);
-    _scale_font = pango_font_description_new();
-    pango_font_description_set_size(_scale_font, 12 * PANGO_SCALE);
-    pango_layout_set_font_description(_scale_layout, _scale_font);
-
-    /* zoom box */
-    _zoom_context = gtk_widget_get_pango_context(_map_widget);
-    _zoom_layout = pango_layout_new(_zoom_context);
-    _zoom_font = pango_font_description_new();
-    pango_font_description_set_size(_zoom_font, 12 * PANGO_SCALE);
-    pango_layout_set_font_description(_zoom_layout, _zoom_font);
-    pango_layout_set_alignment(_zoom_layout, PANGO_ALIGN_CENTER);
-
-    /* speed limit */
-    _speed_limit_gc1 = gdk_gc_new (_map_widget->window);
-    color.red = 0xffff;
-    color.green = 0;
-    color.blue = 0;
-    gdk_gc_set_rgb_fg_color(_speed_limit_gc1, &color);
-    color.red = 0;
-    color.green = 0;
-    color.blue = 0;
-    _speed_limit_gc2 = gdk_gc_new(_map_widget->window);
-    gdk_gc_set_rgb_fg_color(_speed_limit_gc2, &color);
-    _speed_limit_context = gtk_widget_get_pango_context(_map_widget);
-    _speed_limit_layout = pango_layout_new(_speed_limit_context);
-    _speed_limit_fontdesc =  pango_font_description_new();
-    pango_font_description_set_size(_speed_limit_fontdesc, 64 * PANGO_SCALE);
-    pango_layout_set_font_description(_speed_limit_layout,
-            _speed_limit_fontdesc);
-    pango_layout_set_alignment(_speed_limit_layout, PANGO_ALIGN_CENTER);
-
-    /* draw_sat_info() */
-    _sat_info_gc1 = gdk_gc_new(_map_widget->window);
-    color.red = 0;
-    color.green = 0;
-    color.blue = 0;
-    gdk_gc_set_rgb_fg_color(_sat_info_gc1, &color);
-    color.red = 0;
-    color.green = 0;
-    color.blue = 0xffff;
-    _sat_info_gc2 = gdk_gc_new(_map_widget->window);
-    gdk_gc_set_rgb_fg_color(_sat_info_gc2, &color);
-    _sat_info_context = gtk_widget_get_pango_context(_map_widget);
-    _sat_info_layout = pango_layout_new(_sat_info_context);
-    _sat_info_fontdesc =  pango_font_description_new();
-    pango_font_description_set_family(_sat_info_fontdesc,"Sans Serif");
-    pango_font_description_set_size(_sat_info_fontdesc, 8*PANGO_SCALE);
-    pango_layout_set_font_description(_sat_info_layout, _sat_info_fontdesc);
-    pango_layout_set_alignment(_sat_info_layout, PANGO_ALIGN_CENTER);
-
-    /* sat_panel_expose() */
-    _sat_panel_context = gtk_widget_get_pango_context(_map_widget);
-    _sat_panel_layout = pango_layout_new(_sat_panel_context);
-    _sat_panel_fontdesc =  pango_font_description_new();
-    pango_font_description_set_family(_sat_panel_fontdesc,"Sans Serif");
-    pango_font_description_set_size(_sat_panel_fontdesc, 14*PANGO_SCALE);
-    pango_layout_set_font_description (_sat_panel_layout, _sat_panel_fontdesc);
-
-    /* heading_panel_expose() */
-    _heading_panel_context = gtk_widget_get_pango_context(_map_widget);
-    _heading_panel_layout = pango_layout_new(_heading_panel_context);
-    _heading_panel_fontdesc =  pango_font_description_new();
-    pango_font_description_set_family(_heading_panel_fontdesc,"Sans Serif");
-
-    /* draw_sat_details() */
-    _sat_details_context = gtk_widget_get_pango_context(_map_widget);
-    _sat_details_layout = pango_layout_new(_sat_details_context);
-    _sat_details_fontdesc =  pango_font_description_new();
-
-    pango_font_description_set_family(_sat_details_fontdesc,"Sans Serif");
-    pango_font_description_set_size(_sat_details_fontdesc, 10*PANGO_SCALE);
-    pango_layout_set_font_description(_sat_details_layout,
-            _sat_details_fontdesc);
-    pango_layout_set_alignment(_sat_details_layout, PANGO_ALIGN_CENTER);
-
-    /* sat_details_panel_expose() */
-    _sat_details_expose_context = gtk_widget_get_pango_context(_map_widget);
-    _sat_details_expose_layout = pango_layout_new(_sat_details_expose_context);
-    _sat_details_expose_fontdesc =  pango_font_description_new();
-    pango_font_description_set_family(
-            _sat_details_expose_fontdesc,"Sans Serif");
-    pango_layout_set_alignment(_sat_details_expose_layout,
-            PANGO_ALIGN_CENTER);
-    pango_font_description_set_size(_sat_details_expose_fontdesc,
-            14*PANGO_SCALE);
-    pango_layout_set_font_description(_sat_details_expose_layout,
-            _sat_details_expose_fontdesc);
-
-
-    /* set XML_TZONE */
-    {
-        time_t time1;
-        struct tm time2;
-        time1 = time(NULL);
-        localtime_r(&time1, &time2);
-        snprintf(XML_TZONE, sizeof(XML_TZONE), "%+03ld:%02ld",
-                (time2.tm_gmtoff / 60 / 60), (time2.tm_gmtoff / 60) % 60);
-        _gmtoffset = time2.tm_gmtoff;
-    }
-
-    _last_spoken_phrase = g_strdup("");
-
-    memset(&_autoroute_data, 0, sizeof(_autoroute_data));
-
-    integerize_data();
-
-    /* Initialize our line styles. */
-    update_gcs();
-
-    menu_init();
-
-    /* If present, attempt to load the file specified on the command line. */
-    if(argc > 1)
-    {
-        GnomeVFSResult vfs_result;
-        gint size;
-        gchar *buffer;
-        gchar *file_uri;
-
-        /* Get the selected filename. */
-        file_uri = gnome_vfs_make_uri_from_shell_arg(argv[1]);
-
-        if(GNOME_VFS_OK != (vfs_result = gnome_vfs_read_entire_file(
-                        file_uri, &size, &buffer)))
-        {
-            gchar buffer[BUFFER_SIZE];
-            snprintf(buffer, sizeof(buffer),
-                    "%s:\n%s", _("Failed to open file for reading"),
-                    gnome_vfs_result_to_string(vfs_result));
-            popup_error(_window, buffer);
-        }
-        else
-        {
-            if(parse_gpx(&_route, buffer, size, 0))
-            {
-                MACRO_BANNER_SHOW_INFO(_window, _("Route Opened"));
-            }
-            else
-                popup_error(_window, _("Error parsing GPX file."));
-            g_free(buffer);
-        }
-        g_free(file_uri);
-    }
-
-    /* If we have a route, calculate the next point. */
-    route_find_nearest_point();
-
-    /* Add D-BUS signal handler for 'status_changed' */
-    {
-        DBusConnection *dbus_conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
-        gchar *filter_string = g_strdup_printf(
-                "interface=%s", ICD_DBUS_INTERFACE);
-        /* add match */
-        dbus_bus_add_match(dbus_conn, filter_string, NULL);
-
-        g_free (filter_string);
-
-        /* add the callback */
-        dbus_connection_add_filter(dbus_conn,
-                    get_connection_status_signal_cb,
-                    NULL, NULL);
-    }
-    osso_iap_cb(iap_callback);
-
-    {
-        DBusGConnection *dbus_conn;
-        GError *error = NULL;
-
-        /* Initialize D-Bus. */
-        if(NULL == (dbus_conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error)))
-        {
-            g_printerr("Failed to open connection to D-Bus: %s.\n",
-                    error->message);
-            error = NULL;
-        }
-
-        if(NULL == (_rfcomm_req_proxy = dbus_g_proxy_new_for_name(
-                        dbus_conn,
-                        BTCOND_SERVICE,
-                        BTCOND_REQ_PATH,
-                        BTCOND_REQ_INTERFACE)))
-        {
-            g_printerr("Failed to open connection to %s.\n",
-                    BTCOND_REQ_INTERFACE);
-        }
-    }
-
-#ifdef DEBUG
-    _iap_connected = TRUE;
-#endif
-
-    gtk_idle_add((GSourceFunc)window_present, NULL);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static gboolean
-get_nearest_poi(guint unitx, guint unity, PoiInfo *poi)
-{
-    printf("%s(%d, %d)\n", __PRETTY_FUNCTION__, unitx, unity);
-    gboolean result;
-    gfloat lat, lon;
-    unit2latlon(unitx, unity, lat, lon);
-
-    if(SQLITE_OK == sqlite3_bind_double(_stmt_select_nearest_poi, 1, lat)
-    && SQLITE_OK == sqlite3_bind_double(_stmt_select_nearest_poi, 2, lon)
-        && SQLITE_ROW == sqlite3_step(_stmt_select_nearest_poi))
-    {
-        poi->poi_id = sqlite3_column_int(_stmt_select_nearest_poi, 0);
-        poi->cat_id = sqlite3_column_int(_stmt_select_nearest_poi, 1);
-        poi->lat = sqlite3_column_double(_stmt_select_nearest_poi, 2);
-        poi->lon = sqlite3_column_double(_stmt_select_nearest_poi, 3);
-        poi->label =g_strdup(sqlite3_column_text(_stmt_select_nearest_poi, 4));
-        poi->desc = g_strdup(sqlite3_column_text(_stmt_select_nearest_poi, 5));
-        poi->clabel=g_strdup(sqlite3_column_text(_stmt_select_nearest_poi, 6));
-        result = TRUE;
-    }
-    else
-        result = FALSE;
-    sqlite3_reset(_stmt_select_nearest_poi);
-    vprintf("%s(): return %d\n", __PRETTY_FUNCTION__, result);
-    return result;
-}
-
-static gboolean
-select_poi(guint unitx, guint unity, PoiInfo *poi, gboolean quick)
-{
-    guint x, y;
-    gfloat lat1, lon1, lat2, lon2;
-    static GtkWidget *dialog = NULL;
-    static GtkWidget *list = NULL;
-    static GtkWidget *sw = NULL;
-    static GtkTreeViewColumn *column = NULL;
-    static GtkCellRenderer *renderer = NULL;
-    GtkListStore *store = NULL;
-    GtkTreeIter iter;
-    gboolean selected = FALSE;
-    gchar tmp1[LL_FMT_LEN], tmp2[LL_FMT_LEN];
-    guint num_cats = 0;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    x = unitx - pixel2unit(3 * _draw_width);
-    y = unity + pixel2unit(3 * _draw_width);
-    unit2latlon(x, y, lat1, lon1);
-
-    x = unitx + pixel2unit(3 * _draw_width);
-    y = unity - pixel2unit(3 * _draw_width);
-    unit2latlon(x, y, lat2, lon2);
-
-    if(SQLITE_OK != sqlite3_bind_double(_stmt_select_poi, 1, lat1) ||
-          SQLITE_OK != sqlite3_bind_double(_stmt_select_poi, 2, lat2) ||
-          SQLITE_OK != sqlite3_bind_double(_stmt_select_poi, 3, lon1) ||
-          SQLITE_OK != sqlite3_bind_double(_stmt_select_poi, 4, lon2))
-    {
-        g_printerr("Failed to bind values for _stmt_select_poi\n");
-        return FALSE;
-    }
-
-    /* Initialize store. */
-    store = gtk_list_store_new(POI_NUM_COLUMNS,
-                               G_TYPE_INT,    /* POI ID */
-                               G_TYPE_INT,    /* Category ID */
-                               G_TYPE_FLOAT,  /* Latitude */
-                               G_TYPE_FLOAT,  /* Longitude */
-                               G_TYPE_STRING, /* Lat/Lon */
-                               G_TYPE_STRING, /* POI Label */
-                               G_TYPE_STRING, /* POI Desc. */
-                               G_TYPE_STRING);/* Category Label */
-
-    while(SQLITE_ROW == sqlite3_step(_stmt_select_poi))
-    {
-        gfloat lat, lon;
-        lat = sqlite3_column_double(_stmt_select_poi, 0);
-        lon = sqlite3_column_double(_stmt_select_poi, 1);
-        lat_format(lat, tmp1);
-        lon_format(lon, tmp2);
-        gtk_list_store_append(store, &iter);
-        gtk_list_store_set(store, &iter,
-                POI_POIID, sqlite3_column_int(_stmt_select_poi, 2),
-                POI_CATID, sqlite3_column_int(_stmt_select_poi, 5),
-                POI_LAT, lat,
-                POI_LON, lon,
-                POI_LATLON, g_strdup_printf("%s, %s", tmp1, tmp2),
-                POI_LABEL, sqlite3_column_text(_stmt_select_poi, 3),
-                POI_DESC, sqlite3_column_text(_stmt_select_poi, 4),
-                POI_CATLAB, sqlite3_column_text(_stmt_select_poi, 6),
-                -1);
-        num_cats++;
-    }
-    sqlite3_reset(_stmt_select_poi);
-
-    switch(num_cats)
-    {
-        case 0:
-            g_object_unref(G_OBJECT(store));
-            if(!quick)
-            {
-                MACRO_BANNER_SHOW_INFO(_window, _("No POIs found."));
-            }
-            return FALSE;
-            break;
-        case 1:
-            /* iter is still set to the most-recently added POI. */
-            gtk_tree_model_get(GTK_TREE_MODEL(store),
-                &iter,
-                POI_POIID, &(poi->poi_id),
-                POI_CATID, &(poi->cat_id),
-                POI_LAT, &(poi->lat),
-                POI_LON, &(poi->lon),
-                POI_LABEL, &(poi->label),
-                POI_DESC, &(poi->desc),
-                POI_CATLAB, &(poi->clabel),
-                -1);
-            g_object_unref(G_OBJECT(store));
-            return TRUE;
-            break;
-        default:
-            if(quick)
-            {
-                g_object_unref(G_OBJECT(store));
-                return get_nearest_poi(unitx, unity, poi);
-            }
-    }
-
-    /* There are at least 2 matching POI's - let the user select one. */
-    if(dialog == NULL)
-    {
-        dialog = gtk_dialog_new_with_buttons(_("Select POI"),
-                GTK_WINDOW(_window), GTK_DIALOG_MODAL,
-                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
-                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
-                NULL);
-
-        gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 300);
-
-        sw = gtk_scrolled_window_new (NULL, NULL);
-        gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
-                GTK_SHADOW_ETCHED_IN);
-        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
-                GTK_POLICY_NEVER,
-                GTK_POLICY_AUTOMATIC);
-        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
-                sw, TRUE, TRUE, 0);
-
-        list = gtk_tree_view_new();
-        gtk_container_add(GTK_CONTAINER(sw), list);
-
-        gtk_tree_selection_set_mode(
-                gtk_tree_view_get_selection(GTK_TREE_VIEW(list)),
-                GTK_SELECTION_SINGLE);
-        gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(list), TRUE);
-
-        renderer = gtk_cell_renderer_text_new();
-        column = gtk_tree_view_column_new_with_attributes(
-                _("Location"), renderer, "text", POI_LATLON, NULL);
-        gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);
-
-        renderer = gtk_cell_renderer_text_new();
-        column = gtk_tree_view_column_new_with_attributes(
-                _("Label"), renderer, "text", POI_LABEL, NULL);
-        gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);
-
-        renderer = gtk_cell_renderer_text_new();
-        column = gtk_tree_view_column_new_with_attributes(
-                _("Category"), renderer, "text", POI_CATLAB, NULL);
-        gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);
-    }
-
-    gtk_tree_view_set_model(GTK_TREE_VIEW(list), GTK_TREE_MODEL(store));
-    g_object_unref(G_OBJECT(store));
-
-    gtk_widget_show_all(dialog);
-
-    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
-    {
-        if(gtk_tree_selection_get_selected(
-                    gtk_tree_view_get_selection(GTK_TREE_VIEW(list)),
-                    NULL, &iter))
-        {
-            gtk_tree_model_get(GTK_TREE_MODEL(store),
-                &iter, POI_POIID, &(poi->poi_id), -1);
-            gtk_tree_model_get(GTK_TREE_MODEL(store),
-                &iter, POI_CATID, &(poi->cat_id), -1);
-            gtk_tree_model_get(GTK_TREE_MODEL(store),
-                &iter, POI_LAT, &(poi->lat), -1);
-            gtk_tree_model_get(GTK_TREE_MODEL(store),
-                &iter, POI_LON, &(poi->lon), -1);
-            gtk_tree_model_get(GTK_TREE_MODEL(store),
-                &iter, POI_LABEL, &(poi->label), -1);
-            gtk_tree_model_get(GTK_TREE_MODEL(store),
-                &iter, POI_DESC, &(poi->desc), -1);
-            gtk_tree_model_get(GTK_TREE_MODEL(store),
-                &iter, POI_CATLAB, &(poi->clabel), -1);
-            selected = TRUE;
-            break;
-        }
-        else
-            popup_error(dialog, _("Select one POI from the list."));
-    }
-
-    gtk_widget_hide(dialog);
-
-    vprintf("%s(): return %d\n", __PRETTY_FUNCTION__, selected);
-    return selected;
-}
-
-/****************************************************************************
- * ABOVE: ROUTINES **********************************************************
- ****************************************************************************/
-
-
-
-/****************************************************************************
- * BELOW: MAIN **************************************************************
- ****************************************************************************/
-
-gint
-main(gint argc, gchar *argv[])
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    /* Initialize localization. */
-    setlocale(LC_ALL, "");
-    bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
-    bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
-    textdomain(GETTEXT_PACKAGE);
-
-    g_thread_init(NULL);
-
-    /* Initialize _osso. */
-    _osso = osso_initialize("com.gnuite.maemo_mapper", VERSION, TRUE, NULL);
-    if(!_osso)
-    {
-        g_printerr("osso_initialize failed.\n");
-        return 1;
-    }
-
-    gtk_init(&argc, &argv);
-
-    /* Init gconf. */
-    g_type_init();
-    gconf_init(argc, argv, NULL);
-
-    /* Init Gnome-VFS. */
-    gnome_vfs_init();
-
-    /* Init libcurl. */
-    curl_global_init(CURL_GLOBAL_NOTHING);
-
-    maemo_mapper_init(argc, argv);
-
-    if(OSSO_OK != osso_rpc_set_default_cb_f(_osso, dbus_cb_default, NULL))
-    {
-        g_printerr("osso_rpc_set_default_cb_f failed.\n");
-        return 1;
-    }
-
-    gtk_main();
-
-    maemo_mapper_destroy();
-
-    osso_deinitialize(_osso);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-    return 0;
-}
-
-/****************************************************************************
- * ABOVE: MAIN **************************************************************
- ****************************************************************************/
-
-
-
-/****************************************************************************
- * BELOW: CALLBACKS *********************************************************
- ****************************************************************************/
-
-static gint
-dbus_cb_default(const gchar *interface, const gchar *method,
-        GArray *arguments, gpointer data, osso_rpc_t *retval)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(!strcmp(method, "top_application"))
-        gtk_idle_add((GSourceFunc)window_present, NULL);
-
-    retval->type = DBUS_TYPE_INVALID;
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-    return OSSO_OK;
-}
-
-static void
-osso_cb_hw_state(osso_hw_state_t *state, gpointer data)
-{
-    static gboolean _must_save_data = FALSE;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(state->system_inactivity_ind)
-    {
-        if(_must_save_data)
-            _must_save_data = FALSE;
-        else
-        {
-            if(_conn_state > RCVR_OFF)
-            {
-                GConfClient *gconf_client = gconf_client_get_default();
-                if(!gconf_client || gconf_client_get_bool(
-                            gconf_client, GCONF_KEY_DISCONNECT_ON_COVER, NULL))
-                {
-                    gconf_client_clear_cache(gconf_client);
-                    g_object_unref(gconf_client);
-                    set_conn_state(RCVR_OFF);
-                    rcvr_disconnect();
-                    track_add(0, FALSE);
-                    /* Pretend autoroute is in progress to avoid download. */
-                    if(_autoroute_data.enabled)
-                        _autoroute_data.in_progress = TRUE;
-                }
-            }
-            if(_curl_sid)
-            {
-                g_source_remove(_curl_sid);
-                _curl_sid = 0;
-            }
-        }
-    }
-    else if(state->save_unsaved_data_ind)
-    {
-        config_save();
-        _must_save_data = TRUE;
-    }
-    else
-    {
-        if(_conn_state == RCVR_OFF && _enable_gps)
-        {
-            set_conn_state(RCVR_DOWN);
-            rcvr_connect_later();
-            if(_autoroute_data.enabled)
-                _autoroute_data.in_progress = TRUE;
-        }
-
-        /* Start curl in case there are downloads pending. */
-        if(_iap_connected && !_curl_sid)
-            _curl_sid = g_timeout_add(100,
-                    (GSourceFunc)curl_download_timeout, NULL);
-    }
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static gboolean
-key_zoom_timeout()
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-    if(_key_zoom_new < _zoom)
-    {
-        /* We're currently zooming in (_zoom is decreasing). */
-        guint test = _key_zoom_new - _curr_repo->view_zoom_steps;
-        if(test < MAX_ZOOM)
-            /* We can zoom some more.  Hurray! */
-            _key_zoom_new = test;
-        else
-            /* We can't zoom anymore.  Booooo! */
-            return FALSE;
-    }
-    else
-    {
-        /* We're currently zooming out (_zoom is increasing). */
-        guint test = _key_zoom_new + _curr_repo->view_zoom_steps;
-        if(test < MAX_ZOOM)
-            /* We can zoom some more.  Hurray! */
-            _key_zoom_new = test;
-        else
-            /* We can't zoom anymore.  Booooo! */
-            return FALSE;
-    }
-
-    /* We can zoom more - tell them how much they're zooming. */
-    if (!_show_zoomlevel) {
-      gchar buffer[32];
-      snprintf(buffer, sizeof(buffer),
-              "%s %d", _("Zoom to Level"), _key_zoom_new);
-      MACRO_BANNER_SHOW_INFO(_window, buffer);
-    }
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static void
-reset_bluetooth()
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-    if(system("/usr/bin/sudo -l | grep -q '/usr/sbin/hciconfig  *hci0  *reset'"
-            " && sudo /usr/sbin/hciconfig hci0 reset"))
-        popup_error(_window,
-                _("An error occurred while trying to reset the bluetooth "
-                "radio.\n\n"
-                "Did you make sure to modify\nthe /etc/sudoers file?"));
-    else if(_conn_state > RCVR_OFF)
-    {
-        set_conn_state(RCVR_DOWN);
-        rcvr_connect_later();
-    }
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static gboolean
-window_cb_key_press(GtkWidget* widget, GdkEventKey *event)
-{
-    CustomKey custom_key;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    switch(event->keyval)
-    {
-        case HILDON_HARDKEY_UP:
-            custom_key = CUSTOM_KEY_UP;
-            break;
-        case HILDON_HARDKEY_DOWN:
-            custom_key = CUSTOM_KEY_DOWN;
-            break;
-        case HILDON_HARDKEY_LEFT:
-            custom_key = CUSTOM_KEY_LEFT;
-            break;
-        case HILDON_HARDKEY_RIGHT:
-            custom_key = CUSTOM_KEY_RIGHT;
-            break;
-        case HILDON_HARDKEY_SELECT:
-            custom_key = CUSTOM_KEY_SELECT;
-            break;
-        case HILDON_HARDKEY_INCREASE:
-            custom_key = CUSTOM_KEY_INCREASE;
-            break;
-        case HILDON_HARDKEY_DECREASE:
-            custom_key = CUSTOM_KEY_DECREASE;
-            break;
-        case HILDON_HARDKEY_FULLSCREEN:
-            custom_key = CUSTOM_KEY_FULLSCREEN;
-            break;
-        case HILDON_HARDKEY_ESC:
-            custom_key = CUSTOM_KEY_ESC;
-            break;
-        default:
-            vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
-            return FALSE;
-    }
-
-    switch(_action[custom_key])
-    {
-        case CUSTOM_ACTION_PAN_NORTH:
-            map_pan(0, -PAN_UNITS);
-            break;
-
-        case CUSTOM_ACTION_PAN_WEST:
-            map_pan(-PAN_UNITS, 0);
-            break;
-
-        case CUSTOM_ACTION_PAN_SOUTH:
-            map_pan(0, PAN_UNITS);
-            break;
-
-        case CUSTOM_ACTION_PAN_EAST:
-            map_pan(PAN_UNITS, 0);
-            break;
-
-        case CUSTOM_ACTION_TOGGLE_AUTOCENTER:
-            switch(_center_mode)
-            {
-                case CENTER_LATLON:
-                case CENTER_WAS_LEAD:
-                    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(
-                                _menu_ac_lead_item), TRUE);
-                    break;
-                case CENTER_LEAD:
-                case CENTER_WAS_LATLON:
-                    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(
-                                _menu_ac_latlon_item), TRUE);
-                    break;
-            }
-            break;
-
-        case CUSTOM_ACTION_ZOOM_IN:
-        case CUSTOM_ACTION_ZOOM_OUT:
-            if(!_key_zoom_timeout_sid)
-            {
-                _key_zoom_new = _zoom
-                    + (_action[custom_key] == CUSTOM_ACTION_ZOOM_IN
-                            ? -_curr_repo->view_zoom_steps
-                            : _curr_repo->view_zoom_steps);
-                /* Remember, _key_zoom_new is unsigned. */
-                if(_key_zoom_new < MAX_ZOOM)
-                {
-                    if (!_show_zoomlevel) {
-                        gchar buffer[80];
-                        snprintf(buffer, sizeof(buffer),"%s %d",
-                                _("Zoom to Level"), _key_zoom_new);
-                        MACRO_BANNER_SHOW_INFO(_window, buffer);
-                    }
-                    _key_zoom_timeout_sid = g_timeout_add(
-                            500, key_zoom_timeout, NULL);
-                }
-            }
-            break;
-
-        case CUSTOM_ACTION_TOGGLE_FULLSCREEN:
-            gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(
-                        _menu_fullscreen_item), !_fullscreen);
-            break;
-
-        case CUSTOM_ACTION_TOGGLE_TRACKS:
-            switch(_show_tracks)
-            {
-                case 0:
-                    /* Nothing shown, nothing saved; just set both. */
-                    _show_tracks = TRACKS_MASK | ROUTES_MASK;
-                    break;
-                case TRACKS_MASK << 16:
-                case ROUTES_MASK << 16:
-                case (ROUTES_MASK | TRACKS_MASK) << 16:
-                    /* Something was saved and nothing changed since.
-                     * Restore saved. */
-                    _show_tracks = _show_tracks >> 16;
-                    break;
-                default:
-                    /* There is no history, or they changed something
-                     * since the last historical change. Save and
-                     * clear. */
-                    _show_tracks = _show_tracks << 16;
-            }
-            gtk_check_menu_item_set_active(
-                    GTK_CHECK_MENU_ITEM(_menu_show_routes_item),
-                    _show_tracks & ROUTES_MASK);
-
-            gtk_check_menu_item_set_active(
-                    GTK_CHECK_MENU_ITEM(_menu_show_tracks_item),
-                    _show_tracks & TRACKS_MASK);
-
-        case CUSTOM_ACTION_TOGGLE_SCALE:
-            gtk_check_menu_item_set_active(
-                    GTK_CHECK_MENU_ITEM(_menu_show_scale_item),
-                    !_show_scale);
-            break;
-
-        case CUSTOM_ACTION_TOGGLE_POI:
-            gtk_check_menu_item_set_active(
-                    GTK_CHECK_MENU_ITEM(_menu_show_poi_item),
-                    !_show_poi);
-            break;
-        case CUSTOM_ACTION_CHANGE_REPO: {
-            GList *curr = g_list_find(_repo_list, _curr_repo);
-            if(!curr)
-                break;
-
-            /* Loop until we reach a next-able repo, or until we get
-             * back to the current repo. */
-            while((curr = (curr->next ? curr->next : _repo_list))
-                    && !((RepoData*)curr->data)->nextable
-                    && curr->data != _curr_repo) { }
-
-            if(curr->data != _curr_repo)
-            {
-                repo_set_curr(curr->data);
-                gtk_check_menu_item_set_active(
-                        GTK_CHECK_MENU_ITEM(_curr_repo->menu_item),
-                        TRUE);
-            }
-            else
-            {
-                popup_error(_window,
-                    _("There are no other next-able repositories."));
-            }
-            break;
-        }
-
-        case CUSTOM_ACTION_RESET_BLUETOOTH:
-            reset_bluetooth();
-            break;
-
-        case CUSTOM_ACTION_ROUTE_DISTNEXT:
-            route_show_distance_to_next();
-            break;
-
-        case CUSTOM_ACTION_ROUTE_DISTLAST:
-            route_show_distance_to_last();
-            break;
-
-        case CUSTOM_ACTION_TRACK_BREAK:
-            track_insert_break();
-            break;
-
-        case CUSTOM_ACTION_TRACK_CLEAR:
-            track_clear();
-            break;
-
-        case CUSTOM_ACTION_TRACK_DISTLAST:
-            track_show_distance_from_last();
-            break;
-
-        case CUSTOM_ACTION_TRACK_DISTFIRST:
-            track_show_distance_from_first();
-            break;
-
-        case CUSTOM_ACTION_TOGGLE_GPS:
-            gtk_check_menu_item_set_active(
-                    GTK_CHECK_MENU_ITEM(_menu_enable_gps_item),
-                    !_enable_gps);
-            break;
-
-        case CUSTOM_ACTION_TOGGLE_GPSINFO:
-            gtk_check_menu_item_set_active(
-                    GTK_CHECK_MENU_ITEM(_menu_gps_show_info_item),
-                    !_gps_info);
-            break;
-
-        case CUSTOM_ACTION_TOGGLE_SPEEDLIMIT:
-            _speed_limit_on ^= 1;
-            break;
-
-        default:
-            vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
-            return FALSE;
-    }
-
-    return TRUE;
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-}
-
-static gboolean
-window_cb_key_release(GtkWidget* widget, GdkEventKey *event)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    switch(event->keyval)
-    {
-        case HILDON_HARDKEY_INCREASE:
-        case HILDON_HARDKEY_DECREASE:
-            if(_key_zoom_timeout_sid)
-            {
-                g_source_remove(_key_zoom_timeout_sid);
-                _key_zoom_timeout_sid = 0;
-                map_set_zoom(_key_zoom_new);
-            }
-            return TRUE;
-
-        default:
-            return FALSE;
-    }
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static gboolean
-map_cb_configure(GtkWidget *widget, GdkEventConfigure *event)
-{
-    printf("%s(%d, %d)\n", __PRETTY_FUNCTION__,
-            _map_widget->allocation.width, _map_widget->allocation.height);
-
-    _screen_width_pixels = _map_widget->allocation.width;
-    _screen_height_pixels = _map_widget->allocation.height;
-    _screen_grids_halfwidth = pixel2grid(_screen_width_pixels) / 2;
-    _screen_grids_halfheight = pixel2grid(_screen_height_pixels) / 2;
-
-    /* Set _scale_rect. */
-    _scale_rect.x = (_screen_width_pixels - SCALE_WIDTH) / 2;
-    _scale_rect.width = SCALE_WIDTH;
-    pango_layout_set_text(_scale_layout, "0", -1);
-    pango_layout_get_pixel_size(_scale_layout, NULL, &_scale_rect.height);
-    _scale_rect.y = _screen_height_pixels - _scale_rect.height - 1;
-
-    /* Set _zoom rect. */
-    pango_layout_set_text(_zoom_layout, "00", -1);
-    pango_layout_get_pixel_size(_zoom_layout, &_zoom_rect.width,
-            &_zoom_rect.height);
-    _zoom_rect.width *= 1.25;
-    pango_layout_set_width(_zoom_layout, _zoom_rect.width);
-    pango_layout_context_changed(_zoom_layout);
-    _zoom_rect.x = _scale_rect.x - _zoom_rect.width;
-    _zoom_rect.y = _screen_height_pixels - _zoom_rect.height - 1;
-
-
-    MACRO_RECALC_FOCUS_BASE();
-    MACRO_RECALC_FOCUS_SIZE();
-
-    _min_center.unitx = pixel2unit(grid2pixel(_screen_grids_halfwidth));
-    _min_center.unity = pixel2unit(grid2pixel(_screen_grids_halfheight));
-    _max_center.unitx = WORLD_SIZE_UNITS-grid2unit(_screen_grids_halfwidth) -1;
-    _max_center.unity = WORLD_SIZE_UNITS-grid2unit(_screen_grids_halfheight)-1;
-
-    map_center_unit(_center.unitx, _center.unity);
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-sat_panel_expose(GtkWidget *widget, GdkEventExpose *event)
-{
-    gchar *tmp = NULL;
-    guint x, y;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    draw_sat_info(widget,
-        0, 0,
-        widget->allocation.width,
-        widget->allocation.height,
-        FALSE);
-
-    /* Sat View/In Use */
-    tmp = g_strdup_printf("%d/%d", _gps.satinuse, _gps.satinview);
-    pango_layout_set_text(_sat_panel_layout, tmp, -1);
-    pango_layout_set_alignment(_sat_panel_layout, PANGO_ALIGN_LEFT);
-    gdk_draw_layout(widget->window,
-        widget->style->fg_gc[GTK_STATE_NORMAL],
-        20, 2,
-        _sat_panel_layout);
-    g_free(tmp);
-
-    switch(_gps.fix)
-    {
-        case 2:
-        case 3: tmp = g_strdup_printf("%dD fix", _gps.fix); break;
-        default: tmp = g_strdup_printf("nofix"); break;
-    }
-    pango_layout_set_text(_sat_panel_layout, tmp, -1);
-    pango_layout_set_alignment(_sat_panel_layout, PANGO_ALIGN_RIGHT);
-    pango_layout_get_pixel_size(_sat_panel_layout, &x, &y);
-    gdk_draw_layout(widget->window,
-        widget->style->fg_gc[GTK_STATE_NORMAL],
-        widget->allocation.width - 20 - x, 2,
-        _sat_panel_layout);
-    g_free(tmp);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-heading_panel_expose(GtkWidget *widget, GdkEventExpose *event)
-{
-    guint size, xoffset, yoffset, i, x, y;
-    gint dir;
-    gfloat tmp;
-    gchar *text;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    size = MIN(widget->allocation.width, widget->allocation.height);
-    if(widget->allocation.width > widget->allocation.height)
-    {
-        xoffset = (widget->allocation.width - widget->allocation.height) / 2;
-        yoffset = 0;
-    }
-    else
-    {
-        xoffset = 0;
-        yoffset = (widget->allocation.height - widget->allocation.width) / 2;
-    }
-    pango_font_description_set_size(_heading_panel_fontdesc,12*PANGO_SCALE);
-    pango_layout_set_font_description(_heading_panel_layout,
-            _heading_panel_fontdesc);
-    pango_layout_set_alignment(_heading_panel_layout, PANGO_ALIGN_CENTER);
-
-    text = g_strdup_printf("%3.0f°", _gps.heading);
-    pango_layout_set_text(_heading_panel_layout, text, -1);
-    pango_layout_get_pixel_size(_heading_panel_layout, &x, &y);
-
-    gdk_draw_layout(widget->window,
-        widget->style->fg_gc[GTK_STATE_NORMAL],
-        xoffset + size/2 - x/2,
-        yoffset + size - y - 2, _heading_panel_layout);
-    g_free(text);
-
-    gdk_draw_arc (widget->window,
-        widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
-        FALSE,
-        xoffset, yoffset + size/2,
-        size, size,
-        0, 64 * 180);
-
-    /* Simple arrow for heading*/
-    gdk_draw_line(widget->window,
-        widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
-        xoffset + size/2 + 3,
-        yoffset + size - y - 5,
-        xoffset + size/2,
-        yoffset + size/2 + 5);
-
-    gdk_draw_line(widget->window,
-        widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
-        xoffset + size/2 - 3,
-        yoffset + size - y - 5,
-        xoffset + size/2,
-        yoffset + size/2 + 5);
-
-    gdk_draw_line(widget->window,
-        widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
-        xoffset + size/2 - 3,
-        yoffset + size - y - 5,
-        xoffset + size/2,
-        yoffset + size - y - 8);
-
-    gdk_draw_line(widget->window,
-        widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
-        xoffset + size/2 + 3,
-        yoffset + size - y - 5,
-        xoffset + size/2,
-        yoffset + size - y - 8);
-
-    gint angle[5] = {-90,-45,0,45,90};
-    gint fsize[5] = {0,4,10,4,0};
-    for(i = 0; i < 5; i++)
-    {
-        dir = (gint)(_gps.heading/45)*45 + angle[i];
-
-        switch(dir)
-        {
-            case   0:
-            case 360: text = g_strdup("N"); break;
-            case  45:
-            case 405:
-                text = g_strdup("NE"); break;
-            case  90:
-                text = g_strdup("E"); break;
-            case 135:
-                text = g_strdup("SE"); break;
-            case 180:
-                text = g_strdup("S"); break;
-            case 225:
-                text = g_strdup("SW"); break;
-            case 270:
-            case -90:
-                text = g_strdup("W"); break;
-            case 315:
-            case -45:
-                text = g_strdup("NW"); break;
-            default :
-                text = g_strdup("??");
-                break;
-        }
-
-        tmp = ((dir - _gps.heading) * (1.f / 180.f)) * PI;
-        gdk_draw_line(widget->window,
-            widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
-            xoffset + size/2 + ((size/2 - 5) * sinf(tmp)),
-            yoffset + size - ((size/2 - 5) * cosf(tmp)),
-            xoffset + size/2 + ((size/2 + 5) * sinf(tmp)),
-            yoffset + size - ((size/2 + 5) * cosf(tmp)));
-
-        x = fsize[i];
-        if(abs((guint)(_gps.heading/45)*45 - _gps.heading)
-                > abs((guint)(_gps.heading/45)*45 + 45 - _gps.heading)
-                && (i > 0))
-            x = fsize[i - 1];
-
-        pango_font_description_set_size(_heading_panel_fontdesc,
-                (10 + x)*PANGO_SCALE);
-        pango_layout_set_font_description(_heading_panel_layout,
-                _heading_panel_fontdesc);
-        pango_layout_set_text(_heading_panel_layout, text, -1);
-        pango_layout_get_pixel_size(_heading_panel_layout, &x, &y);
-        x = xoffset + size/2 + ((size/2 + 15) * sinf(tmp)) - x/2,
-        y = yoffset + size - ((size/2 + 15) * cosf(tmp)) - y/2,
-
-        gdk_draw_layout(widget->window,
-            widget->style->fg_gc[GTK_STATE_NORMAL],
-            x, y, _heading_panel_layout);
-        g_free(text);
-    }
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-map_cb_expose(GtkWidget *widget, GdkEventExpose *event)
-{
-    printf("%s(%d, %d, %d, %d)\n", __PRETTY_FUNCTION__,
-            event->area.x, event->area.y,
-            event->area.width, event->area.height);
-
-    gdk_draw_drawable(
-            _map_widget->window,
-            _gc[COLORABLE_MARK],
-            _map_pixmap,
-            event->area.x + _offsetx, event->area.y + _offsety,
-            event->area.x, event->area.y,
-            event->area.width, event->area.height);
-    map_draw_mark();
-
-    /* draw zoom box if so wanted */
-    if (_show_zoomlevel) {
-      gchar *buffer = g_strdup_printf("%d", _zoom);
-      gdk_draw_rectangle(_map_widget->window,
-              _map_widget->style->bg_gc[GTK_WIDGET_STATE(_map_widget)],
-              TRUE,
-              _zoom_rect.x, _zoom_rect.y,
-              _zoom_rect.width, _zoom_rect.height);
-      gdk_draw_rectangle(_map_widget->window,
-              _map_widget->style->fg_gc[GTK_WIDGET_STATE(_map_widget)],
-              FALSE,
-              _zoom_rect.x, _zoom_rect.y,
-              _zoom_rect.width, _zoom_rect.height);
-      pango_layout_set_text(_zoom_layout, buffer, -1);
-      gdk_draw_layout(_map_widget->window,
-              _map_widget->style->fg_gc[GTK_WIDGET_STATE(_map_widget)],
-              _zoom_rect.x + _zoom_rect.width / 2,
-              _zoom_rect.y, _zoom_layout);
-    }
-
-    /* Draw scale, if necessary. */
-    if(_show_scale)
-    {
-        gdk_rectangle_intersect(&event->area, &_scale_rect, &event->area);
-        if(event->area.width && event->area.height)
-        {
-            gdk_draw_rectangle(_map_widget->window,
-                    _map_widget->style->bg_gc[GTK_WIDGET_STATE(_map_widget)],
-                    TRUE,
-                    _scale_rect.x, _scale_rect.y,
-                    _scale_rect.width, _scale_rect.height);
-            gdk_draw_rectangle(_map_widget->window,
-                    _map_widget->style->fg_gc[GTK_WIDGET_STATE(_map_widget)],
-                    FALSE,
-                    _scale_rect.x, _scale_rect.y,
-                    _scale_rect.width, _scale_rect.height);
-
-            /* Now calculate and draw the distance. */
-            {
-                gchar buffer[16];
-                gfloat distance;
-                gfloat lat1, lon1, lat2, lon2;
-                gint width;
-
-                unit2latlon(_center.unitx - pixel2unit(SCALE_WIDTH / 2 - 4),
-                        _center.unity, lat1, lon1);
-                unit2latlon(_center.unitx + pixel2unit(SCALE_WIDTH / 2 - 4),
-                        _center.unity, lat2, lon2);
-                distance = calculate_distance(lat1, lon1, lat2, lon2)
-                    * UNITS_CONVERT[_units];
-
-                if(distance < 1.f)
-                    snprintf(buffer, sizeof(buffer), "%0.2f %s", distance,
-                            UNITS_TEXT[_units]);
-                else if(distance < 10.f)
-                    snprintf(buffer, sizeof(buffer), "%0.1f %s", distance,
-                            UNITS_TEXT[_units]);
-                else
-                    snprintf(buffer, sizeof(buffer), "%0.f %s", distance,
-                            UNITS_TEXT[_units]);
-                pango_layout_set_text(_scale_layout, buffer, -1);
-
-                pango_layout_get_pixel_size(_scale_layout, &width, NULL);
-
-                /* Draw the layout itself. */
-                gdk_draw_layout(_map_widget->window,
-                    _map_widget->style->fg_gc[GTK_WIDGET_STATE(_map_widget)],
-                    _scale_rect.x + (_scale_rect.width - width) / 2,
-                    _scale_rect.y, _scale_layout);
-
-                /* Draw little hashes on the ends. */
-                gdk_draw_line(_map_widget->window,
-                    _map_widget->style->fg_gc[GTK_WIDGET_STATE(_map_widget)],
-                    _scale_rect.x + 4,
-                    _scale_rect.y + _scale_rect.height / 2 - 4,
-                    _scale_rect.x + 4,
-                    _scale_rect.y + _scale_rect.height / 2 + 4);
-                gdk_draw_line(_map_widget->window,
-                    _map_widget->style->fg_gc[GTK_WIDGET_STATE(_map_widget)],
-                    _scale_rect.x + 4,
-                    _scale_rect.y + _scale_rect.height / 2,
-                    _scale_rect.x + (_scale_rect.width - width) / 2 - 4,
-                    _scale_rect.y + _scale_rect.height / 2);
-                gdk_draw_line(_map_widget->window,
-                    _map_widget->style->fg_gc[GTK_WIDGET_STATE(_map_widget)],
-                    _scale_rect.x + _scale_rect.width - 4,
-                    _scale_rect.y + _scale_rect.height / 2 - 4,
-                    _scale_rect.x + _scale_rect.width - 4,
-                    _scale_rect.y + _scale_rect.height / 2 + 4);
-                gdk_draw_line(_map_widget->window,
-                    _map_widget->style->fg_gc[GTK_WIDGET_STATE(_map_widget)],
-                    _scale_rect.x + _scale_rect.width - 4,
-                    _scale_rect.y + _scale_rect.height / 2,
-                    _scale_rect.x + (_scale_rect.width + width) / 2 + 4,
-                    _scale_rect.y + _scale_rect.height / 2);
-            }
-        }
-    }
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-map_cb_button_press(GtkWidget *widget, GdkEventButton *event)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    _cmenu_position_x = event->x + 0.5;
-    _cmenu_position_y = event->y + 0.5;
-
-    /* Return FALSE to allow context menu to work. */
-    vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
-    return FALSE;
-}
-
-static gboolean
-map_cb_button_release(GtkWidget *widget, GdkEventButton *event)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-#ifdef DEBUG
-    if(event->button != 1)
-    {
-        _pos.unitx = x2unit((gint)(event->x + 0.5));
-        _pos.unity = y2unit((gint)(event->y + 0.5));
-        unit2latlon(_pos.unitx, _pos.unity, _gps.lat, _gps.lon);
-        _gps.speed = 20.f;
-        integerize_data();
-        track_add(time(NULL), FALSE);
-        refresh_mark();
-    }
-    else
-#endif
-    {
-        gboolean selected_poi = FALSE;
-        PoiInfo poi;
-        guint unitx = x2unit((gint)(event->x + 0.5));
-        guint unity = y2unit((gint)(event->y + 0.5));
-
-        if(_show_poi && (_poi_zoom > _zoom))
-        {
-            selected_poi = select_poi(unitx, unity, &poi, TRUE); /*TRUE=quick*/
-            if(selected_poi)
-            {
-                gchar *banner;
-                latlon2unit(poi.lat, poi.lon, unitx, unity);
-                banner = g_strdup_printf("%s (%s)", poi.label, poi.clabel);
-                MACRO_BANNER_SHOW_INFO(_window, banner);
-                g_free(banner);
-                g_free(poi.label);
-                g_free(poi.desc);
-                g_free(poi.clabel);
-            }
-        }
-        if(!selected_poi)
-        {
-            if(_center_mode > 0)
-                gtk_check_menu_item_set_active(
-                        GTK_CHECK_MENU_ITEM(_menu_ac_none_item), TRUE);
-            map_center_unit(
-                    x2unit((gint)(event->x + 0.5)),
-                    y2unit((gint)(event->y + 0.5)));
-        }
-    }
-
-    /* Return FALSE to avoid context menu (if it hasn't popped up already). */
-    vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
-    return FALSE;
-}
-
-static gboolean
-channel_cb_error(GIOChannel *src, GIOCondition condition, gpointer data)
-{
-    printf("%s(%d)\n", __PRETTY_FUNCTION__, condition);
-
-    /* An error has occurred - re-connect(). */
-    rcvr_disconnect();
-    track_add(0, FALSE);
-    _speed_excess = FALSE;
-
-    if(_conn_state > RCVR_OFF)
-    {
-        set_conn_state(RCVR_DOWN);
-        gps_hide_text();
-        rcvr_connect_later();
-    }
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-    return FALSE;
-}
-
-static gboolean
-channel_cb_connect(GIOChannel *src, GIOCondition condition, gpointer data)
-{
-    printf("%s(%d)\n", __PRETTY_FUNCTION__, condition);
-
-    set_conn_state(RCVR_UP);
-    _input_sid = g_io_add_watch_full(_channel, G_PRIORITY_HIGH_IDLE,
-            G_IO_IN | G_IO_PRI, channel_cb_input, NULL, NULL);
-
-    _connect_sid = 0;
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-    return FALSE;
-}
-
-#define MACRO_PARSE_INT(tofill, str) { \
-    gchar *error_check; \
-    (tofill) = strtol((str), &error_check, 10); \
-    if(error_check == (str)) \
-    { \
-        g_printerr("Line %d: Failed to parse string as int: %s\n", \
-                __LINE__, str); \
-        MACRO_BANNER_SHOW_INFO(_window, \
-                _("Invalid NMEA input from receiver!")); \
-        return; \
-    } \
-}
-#define MACRO_PARSE_FLOAT(tofill, str) { \
-    gchar *error_check; \
-    (tofill) = g_ascii_strtod((str), &error_check); \
-    if(error_check == (str)) \
-    { \
-        g_printerr("Failed to parse string as float: %s\n", str); \
-        MACRO_BANNER_SHOW_INFO(_window, \
-                _("Invalid NMEA input from receiver!")); \
-        return; \
-    } \
-}
-static void
-channel_parse_rmc(gchar *sentence)
-{
-    /* Recommended Minimum Navigation Information C
-     *  1) UTC Time
-     *  2) Status, V=Navigation receiver warning A=Valid
-     *  3) Latitude
-     *  4) N or S
-     *  5) Longitude
-     *  6) E or W
-     *  7) Speed over ground, knots
-     *  8) Track made good, degrees true
-     *  9) Date, ddmmyy
-     * 10) Magnetic Variation, degrees
-     * 11) E or W
-     * 12) FAA mode indicator (NMEA 2.3 and later)
-     * 13) Checksum
-     */
-    gchar *token, *dpoint, *gpsdate = NULL;
-    gdouble tmpd = 0.f;
-    guint tmpi = 0;
-    gboolean newly_fixed = FALSE;
-    vprintf("%s(): %s\n", __PRETTY_FUNCTION__, sentence);
-
-#define DELIM ","
-
-    /* Parse time. */
-    token = strsep(&sentence, DELIM);
-    if(token && *token)
-        gpsdate = token;
-
-    token = strsep(&sentence, DELIM);
-    /* Token is now Status. */
-    if(token && *token == 'A')
-    {
-        /* Data is valid. */
-        if(_conn_state != RCVR_FIXED)
-        {
-            newly_fixed = TRUE;
-            set_conn_state(RCVR_FIXED);
-        }
-    }
-    else
-    {
-        /* Data is invalid - not enough satellites?. */
-        if(_conn_state != RCVR_UP)
-        {
-            set_conn_state(RCVR_UP);
-            track_add(0, FALSE);
-        }
-    }
-
-    /* Parse the latitude. */
-    token = strsep(&sentence, DELIM);
-    if(token && *token)
-    {
-        dpoint = strchr(token, '.');
-        if(!dpoint) /* handle buggy NMEA */
-            dpoint = token + strlen(token);
-        MACRO_PARSE_FLOAT(tmpd, dpoint - 2);
-        dpoint[-2] = '\0';
-        MACRO_PARSE_INT(tmpi, token);
-        _gps.lat = tmpi + (tmpd * (1.0 / 60.0));
-    }
-
-    /* Parse N or S. */
-    token = strsep(&sentence, DELIM);
-    if(token && *token == 'S')
-        _gps.lat = -_gps.lat;
-
-    /* Parse the longitude. */
-    token = strsep(&sentence, DELIM);
-    if(token && *token)
-    {
-        dpoint = strchr(token, '.');
-        if(!dpoint) /* handle buggy NMEA */
-            dpoint = token + strlen(token);
-        MACRO_PARSE_FLOAT(tmpd, dpoint - 2);
-        dpoint[-2] = '\0';
-        MACRO_PARSE_INT(tmpi, token);
-        _gps.lon = tmpi + (tmpd * (1.0 / 60.0));
-    }
-
-    /* Parse E or W. */
-    token = strsep(&sentence, DELIM);
-    if(token && *token == 'W')
-        _gps.lon = -_gps.lon;
-
-    /* Parse speed over ground, knots. */
-    token = strsep(&sentence, DELIM);
-    if(token && *token)
-    {
-        MACRO_PARSE_FLOAT(_gps.speed, token);
-        if(_gps.fix > 1)
-            _gps.maxspeed = MAX(_gps.maxspeed, _gps.speed);
-    }
-
-    /* Parse heading, degrees from true north. */
-    token = strsep(&sentence, DELIM);
-    if(token && *token)
-    {
-        MACRO_PARSE_FLOAT(_gps.heading, token);
-    }
-
-    /* Parse date. */
-    token = strsep(&sentence, DELIM);
-    if(token && *token && gpsdate)
-    {
-        struct tm time;
-        gpsdate[6] = '\0'; /* Make sure time is 6 chars long. */
-        strcat(gpsdate, token);
-        strptime(gpsdate, "%H%M%S%d%m%y", &time);
-        _pos.time = mktime(&time) + _gmtoffset;
-    }
-    else
-        _pos.time = time(NULL);
-
-    /* Translate data into integers. */
-    integerize_data();
-
-    /* Add new data to track. */
-    if(_conn_state == RCVR_FIXED)
-        track_add(_pos.time, newly_fixed);
-
-    /* Move mark to new location. */
-    refresh_mark();
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
- static void
-channel_parse_gga(gchar *sentence)
-{
-    /* GGA          Global Positioning System Fix Data
-     1. Fix Time
-     2. Latitude
-     3. N or S
-     4. Longitude
-     5. E or W
-     6. Fix quality
-                   0 = invalid
-                   1 = GPS fix (SPS)
-                   2 = DGPS fix
-                   3 = PPS fix
-                   4 = Real Time Kinematic
-                   5 = Float RTK
-                   6 = estimated (dead reckoning) (2.3 feature)
-                   7 = Manual input mode
-                   8 = Simulation mode
-     7. Number of satellites being tracked
-     8. Horizontal dilution of position
-     9. Altitude, Meters, above mean sea level
-     10. Alt unit (meters)
-     11. Height of geoid (mean sea level) above WGS84 ellipsoid
-     12. unit
-     13. (empty field) time in seconds since last DGPS update
-     14. (empty field) DGPS station ID number
-     15. the checksum data
-     */
-    gchar *token;
-    vprintf("%s(): %s\n", __PRETTY_FUNCTION__, sentence);
-
-#define DELIM ","
-
-    /* Skip Fix time */
-    token = strsep(&sentence, DELIM);
-    /* Skip latitude */
-    token = strsep(&sentence, DELIM);
-    /* Skip N or S */
-    token = strsep(&sentence, DELIM);
-    /* Skip longitude */
-    token = strsep(&sentence, DELIM);
-    /* Skip S or W */
-    token = strsep(&sentence, DELIM);
-
-    /* Parse Fix quality */
-    token = strsep(&sentence, DELIM);
-    if(token && *token)
-        MACRO_PARSE_INT(_gps.fixquality, token);
-
-    /* Skip number of satellites */
-    token = strsep(&sentence, DELIM);
-
-    /* Parse Horizontal dilution of position */
-    token = strsep(&sentence, DELIM);
-    if(token && *token)
-        MACRO_PARSE_INT(_gps.hdop, token);
-
-    /* Altitude */
-    token = strsep(&sentence, DELIM);
-    if(token && *token)
-    {
-        MACRO_PARSE_FLOAT(_pos.altitude, token);
-    }
-    else
-        _pos.altitude = NAN;
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static void
-channel_parse_gsa(gchar *sentence)
-{
-    /* GPS DOP and active satellites
-     *  1) Auto selection of 2D or 3D fix (M = manual)
-     *  2) 3D fix - values include: 1 = no fix, 2 = 2D, 3 = 2D
-     *  3) PRNs of satellites used for fix
-     *     (space for 12)
-     *  4) PDOP (dilution of precision)
-     *  5) Horizontal dilution of precision (HDOP)
-     *  6) Vertical dilution of precision (VDOP)
-     *  7) Checksum
-     */
-    gchar *token;
-    guint i;
-    vprintf("%s(): %s\n", __PRETTY_FUNCTION__, sentence);
-
-#define DELIM ","
-
-    /* Skip Auto selection. */
-    token = strsep(&sentence, DELIM);
-
-    /* 3D fix. */
-    token = strsep(&sentence, DELIM);
-    if(token && *token)
-        MACRO_PARSE_INT(_gps.fix, token);
-
-    _gps.satinuse = 0;
-    for(i = 0; i < 12; i++)
-    {
-        token = strsep(&sentence, DELIM);
-        if(token && *token)
-            _gps.satforfix[_gps.satinuse++] = atoi(token);
-    }
-
-    /* PDOP */
-    token = strsep(&sentence, DELIM);
-    if(token && *token)
-        MACRO_PARSE_FLOAT(_gps.pdop, token);
-
-    /* HDOP */
-    token = strsep(&sentence, DELIM);
-    if(token && *token)
-        MACRO_PARSE_FLOAT(_gps.hdop, token);
-
-    /* VDOP */
-    token = strsep(&sentence, DELIM);
-    if(token && *token)
-        MACRO_PARSE_FLOAT(_gps.vdop, token);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static void
-channel_parse_gsv(gchar *sentence)
-{
-    /* Must be GSV - Satellites in view
-     *  1) total number of messages
-     *  2) message number
-     *  3) satellites in view
-     *  4) satellite number
-     *  5) elevation in degrees (0-90)
-     *  6) azimuth in degrees to true north (0-359)
-     *  7) SNR in dB (0-99)
-     *  more satellite infos like 4)-7)
-     *  n) checksum
-     */
-    gchar *token;
-    guint msgcnt = 0, nummsgs = 0;
-    static guint running_total = 0;
-    static guint num_sats_used = 0;
-    static guint satcnt = 0;
-    vprintf("%s(): %s\n", __PRETTY_FUNCTION__, sentence);
-
-    /* Parse number of messages. */
-    token = strsep(&sentence, DELIM);
-    if(token && *token)
-        MACRO_PARSE_INT(nummsgs, token);
-
-    /* Parse message number. */
-    token = strsep(&sentence, DELIM);
-    if(token && *token)
-        MACRO_PARSE_INT(msgcnt, token);
-
-    /* Parse number of satellites in view. */
-    token = strsep(&sentence, DELIM);
-    if(token && *token)
-    {
-        MACRO_PARSE_INT(_gps.satinview, token);
-        if(_gps.satinview > 12) /* Handle buggy NMEA. */
-            _gps.satinview = 12;
-    }
-
-    /* Loop until there are no more satellites to parse. */
-    while(sentence && satcnt < 12)
-    {
-        /* Get token for Satellite Number. */
-        token = strsep(&sentence, DELIM);
-        if(token && *token)
-            _gps_sat[satcnt].prn = atoi(token);
-
-        /* Get token for elevation in degrees (0-90). */
-        token = strsep(&sentence, DELIM);
-        if(token && *token)
-            _gps_sat[satcnt].elevation = atoi(token);
-
-        /* Get token for azimuth in degrees to true north (0-359). */
-        token = strsep(&sentence, DELIM);
-        if(token && *token)
-            _gps_sat[satcnt].azimuth = atoi(token);
-
-        /* Get token for SNR. */
-        token = strsep(&sentence, DELIM);
-        if(token && *token && (_gps_sat[satcnt].snr = atoi(token)))
-        {
-            /* SNR is non-zero - add to total and count as used. */
-            running_total += _gps_sat[satcnt].snr;
-            num_sats_used++;
-        }
-        satcnt++;
-    }
-
-    if(msgcnt == nummsgs)
-    {
-        /*  This is the last message. Calculate signal strength. */
-        if(num_sats_used)
-        {
-            if(_conn_state == RCVR_UP)
-            {
-                gdouble fraction = running_total * sqrt(num_sats_used)
-                    / num_sats_used / 100.0;
-                BOUND(fraction, 0.0, 1.0);
-                hildon_banner_set_fraction(
-                        HILDON_BANNER(_fix_banner), fraction);
-            }
-            running_total = 0;
-            num_sats_used = 0;
-        }
-        satcnt = 0;
-
-        /* Keep awake while they watch the progress bar. */
-        KEEP_DISPLAY_ON();
-    }
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static gboolean
-channel_cb_input(GIOChannel *src, GIOCondition condition, gpointer data)
-{
-    gsize bytes_read;
-    vprintf("%s(%d)\n", __PRETTY_FUNCTION__, condition);
-
-    if(G_IO_STATUS_NORMAL == g_io_channel_read_chars(
-                _channel,
-                _gps_read_buf_curr,
-                _gps_read_buf_last - _gps_read_buf_curr,
-                &bytes_read,
-                NULL))
-    {
-        gchar *eol;
-        _gps_read_buf_curr += bytes_read;
-        *_gps_read_buf_curr = '\0'; /* append a \0 so we can read as string */
-        while((eol = strchr(_gps_read_buf, '\n')))
-        {
-            gchar *sptr = _gps_read_buf + 1; /* Skip the $ */
-            guint csum = 0;
-            if(*_gps_read_buf == '$')
-            {
-                /* This is the beginning of a sentence; okay to parse. */
-                *eol = '\0'; /* overwrite \n with \0 */
-                while(*sptr && *sptr != '*')
-                    csum ^= *sptr++;
-
-                /* If we're at a \0 (meaning there is no checksum), or if the
-                 * checksum is good, then parse the sentence. */
-                if(!*sptr || csum == strtol(sptr + 1, NULL, 16))
-                {
-                    if(*sptr)
-                        *sptr = '\0'; /* take checksum out of the buffer. */
-                    if(!strncmp(_gps_read_buf + 3, "GSV", 3))
-                    {
-                        if(_conn_state == RCVR_UP
-                                || _gps_info || _satdetails_on)
-                            channel_parse_gsv(_gps_read_buf + 7);
-                    }
-                    else if(!strncmp(_gps_read_buf + 3, "RMC", 3))
-                        channel_parse_rmc(_gps_read_buf + 7);
-                    else if(!strncmp(_gps_read_buf + 3, "GGA", 3))
-                        channel_parse_gga(_gps_read_buf + 7);
-                    else if(!strncmp(_gps_read_buf + 3, "GSA", 3))
-                        channel_parse_gsa(_gps_read_buf + 7);
-
-                    if(_gps_info)
-                        gps_display_data();
-                    if(_satdetails_on)
-                        gps_display_details();
-                }
-                else
-                {
-                    /* There was a checksum, and it was bad. */
-                    g_printerr("%s: Bad checksum in NMEA sentence:\n%s\n",
-                            __PRETTY_FUNCTION__, _gps_read_buf);
-                }
-            }
-
-            /* If eol is at or after (_gps_read_buf_curr - 1) */
-            if(eol >= (_gps_read_buf_curr - 1))
-            {
-                /* Last read was a newline - reset read buffer */
-                _gps_read_buf_curr = _gps_read_buf;
-                *_gps_read_buf_curr = '\0';
-            }
-            else
-            {
-                /* Move the next line to the front of the buffer. */
-                memmove(_gps_read_buf, eol + 1,
-                        _gps_read_buf_curr - eol); /* include terminating 0 */
-                /* Subtract _curr so that it's pointing at the new \0. */
-                _gps_read_buf_curr -= (eol - _gps_read_buf + 1);
-            }
-        }
-    }
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-typedef struct _OriginToggleInfo OriginToggleInfo;
-struct _OriginToggleInfo {
-    GtkWidget *rad_use_gps;
-    GtkWidget *rad_use_route;
-    GtkWidget *rad_use_text;
-    GtkWidget *chk_avoid_highways;
-    GtkWidget *chk_auto;
-    GtkWidget *txt_from;
-    GtkWidget *txt_to;
-};
-
-static gboolean
-origin_type_selected(GtkWidget *toggle,
-        OriginToggleInfo *oti)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle)))
-    {
-        gtk_widget_set_sensitive(oti->txt_from, toggle == oti->rad_use_text);
-        gtk_widget_set_sensitive(oti->chk_auto, toggle == oti->rad_use_gps);
-    }
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-/**
- * Display a dialog box to the user asking them to download a route.  The
- * "From" and "To" textfields may be initialized using the first two
- * parameters.  The third parameter, if set to TRUE, will cause the "Use GPS
- * Location" checkbox to be enabled, which automatically sets the "From" to the
- * current GPS position (this overrides any value that may have been passed as
- * the "To" initializer).
- * None of the passed strings are freed - that is left to the caller, and it is
- * safe to free either string as soon as this function returns.
- */
-static gboolean
-route_download(gchar *to)
-{
-    static GtkWidget *dialog = NULL;
-    static GtkWidget *table = NULL;
-    static GtkWidget *label = NULL;
-    static GtkWidget *txt_source_url = NULL;
-    static OriginToggleInfo oti;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    /* Connect to the internet pre-emptively to prevent lack thereof. */
-    if(!_iap_connected && !_iap_connecting)
-    {
-        _iap_connecting = TRUE;
-        osso_iap_connect(OSSO_IAP_ANY, OSSO_IAP_REQUESTED_CONNECT, NULL);
-    }
-
-    if(dialog == NULL)
-    {
-        GtkEntryCompletion *from_comp;
-        GtkEntryCompletion *to_comp;
-        dialog = gtk_dialog_new_with_buttons(_("Download Route"),
-                GTK_WINDOW(_window), GTK_DIALOG_MODAL,
-                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
-                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
-                NULL);
-
-        /* Enable the help button. */
-        ossohelp_dialog_help_enable(
-                GTK_DIALOG(dialog), HELP_ID_DOWNROUTE, _osso);
-
-        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
-                table = gtk_table_new(2, 5, FALSE), TRUE, TRUE, 0);
-
-        /* Source URL. */
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("Source URL")),
-                0, 1, 0, 1, GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(table),
-                txt_source_url = gtk_entry_new(),
-                1, 3, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-        gtk_entry_set_width_chars(GTK_ENTRY(txt_source_url), 25);
-
-        /* Auto. */
-        gtk_table_attach(GTK_TABLE(table),
-                oti.rad_use_gps = gtk_radio_button_new_with_label(NULL,
-                    _("Use GPS Location")),
-                0, 2, 1, 2, GTK_FILL, 0, 2, 4);
-        gtk_table_attach(GTK_TABLE(table),
-                oti.chk_auto = gtk_check_button_new_with_label(
-                    _("Auto-Update")),
-                2, 3, 1, 2, GTK_FILL, 0, 2, 4);
-
-        /* Use End of Route. */
-        gtk_table_attach(GTK_TABLE(table),
-               oti.rad_use_route = gtk_radio_button_new_with_label_from_widget(
-                   GTK_RADIO_BUTTON(oti.rad_use_gps), _("Use End of Route")),
-               0, 2, 2, 3, GTK_FILL, 0, 2, 4);
-
-        /* Avoid Highways. */
-        gtk_table_attach(GTK_TABLE(table),
-                oti.chk_avoid_highways = gtk_check_button_new_with_label(
-                    _("Avoid Highways")),
-                2, 3, 2, 3, GTK_FILL, 0, 2, 4);
-
-
-        /* Origin. */
-        gtk_table_attach(GTK_TABLE(table),
-                oti.rad_use_text = gtk_radio_button_new_with_label_from_widget(
-                    GTK_RADIO_BUTTON(oti.rad_use_gps), _("Origin")),
-                0, 1, 3, 4, GTK_FILL, 0, 2, 4);
-        gtk_table_attach(GTK_TABLE(table),
-                oti.txt_from = gtk_entry_new(),
-                1, 3, 3, 4, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-        gtk_entry_set_width_chars(GTK_ENTRY(oti.txt_from), 25);
-        g_object_set(G_OBJECT(oti.txt_from), HILDON_AUTOCAP, FALSE, NULL);
-
-        /* Destination. */
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("Destination")),
-                0, 1, 4, 5, GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(table),
-                oti.txt_to = gtk_entry_new(),
-                1, 3, 4, 5, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-        gtk_entry_set_width_chars(GTK_ENTRY(oti.txt_to), 25);
-        g_object_set(G_OBJECT(oti.txt_to), HILDON_AUTOCAP, FALSE, NULL);
-
-
-        /* Set up auto-completion. */
-        from_comp = gtk_entry_completion_new();
-        gtk_entry_completion_set_model(from_comp, GTK_TREE_MODEL(_loc_model));
-        gtk_entry_completion_set_text_column(from_comp, 0);
-        gtk_entry_set_completion(GTK_ENTRY(oti.txt_from), from_comp);
-
-        to_comp = gtk_entry_completion_new();
-        gtk_entry_completion_set_model(to_comp, GTK_TREE_MODEL(_loc_model));
-        gtk_entry_completion_set_text_column(to_comp, 0);
-        gtk_entry_set_completion(GTK_ENTRY(oti.txt_to), to_comp);
-
-
-        g_signal_connect(G_OBJECT(oti.rad_use_gps), "toggled",
-                          G_CALLBACK(origin_type_selected), &oti);
-        g_signal_connect(G_OBJECT(oti.rad_use_route), "toggled",
-                          G_CALLBACK(origin_type_selected), &oti);
-        g_signal_connect(G_OBJECT(oti.rad_use_text), "toggled",
-                          G_CALLBACK(origin_type_selected), &oti);
-
-        //gtk_widget_set_sensitive(oti.chk_auto, FALSE);
-    }
-
-    /* Initialize fields. */
-
-    gtk_entry_set_text(GTK_ENTRY(txt_source_url), _route_dl_url);
-    if(to)
-        gtk_entry_set_text(GTK_ENTRY(oti.txt_to), to);
-
-    /* Use "End of Route" by default if they have a route. */
-    if(_route.head != _route.tail)
-    {
-        /* There is no route, so make it the default. */
-        gtk_widget_set_sensitive(oti.rad_use_route, TRUE);
-        gtk_toggle_button_set_active(
-                GTK_TOGGLE_BUTTON(oti.rad_use_route), TRUE);
-        gtk_widget_grab_focus(oti.rad_use_route);
-    }
-    /* Else use "GPS Location" if they have GPS enabled. */
-    else
-    {
-        /* There is no route, so desensitize "Use End of Route." */
-        gtk_widget_set_sensitive(oti.rad_use_route, FALSE);
-        if(_enable_gps)
-        {
-            gtk_toggle_button_set_active(
-                    GTK_TOGGLE_BUTTON(oti.rad_use_gps), TRUE);
-            gtk_widget_grab_focus(oti.rad_use_gps);
-        }
-        /* Else use text. */
-        else
-        {
-            gtk_toggle_button_set_active(
-                    GTK_TOGGLE_BUTTON(oti.rad_use_text), TRUE);
-            gtk_widget_grab_focus(oti.txt_from);
-        }
-    }
-
-    gtk_widget_show_all(dialog);
-
-    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
-    {
-        CURL *curl_easy;
-        RouteDownloadData rdl_data = {0, 0};
-        gchar *buffer;
-        const gchar *source_url, *from, *to;
-        gchar *from_escaped, *to_escaped;
-
-        source_url = gtk_entry_get_text(GTK_ENTRY(txt_source_url));
-        if(!strlen(source_url))
-        {
-            popup_error(dialog, _("Please specify a source URL."));
-            continue;
-        }
-        else
-        {
-            g_free(_route_dl_url);
-            _route_dl_url = g_strdup(source_url);
-        }
-
-        if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(oti.rad_use_gps)))
-        {
-            gchar buffer[80];
-            gchar strlat[32];
-            gchar strlon[32];
-            g_ascii_formatd(strlat, 32, "%.06f", _gps.lat);
-            g_ascii_formatd(strlon, 32, "%.06f", _gps.lon);
-            snprintf(buffer, sizeof(buffer), "%s, %s", strlat, strlon);
-            from = buffer;
-        }
-        else if(gtk_toggle_button_get_active(
-                    GTK_TOGGLE_BUTTON(oti.rad_use_route)))
-        {
-            gchar buffer[80];
-            gchar strlat[32];
-            gchar strlon[32];
-            Point *p;
-            gfloat lat, lon;
-
-            /* Use last non-zero route point. */
-            for(p = _route.tail; !p->unity; p--) { }
-
-            unit2latlon(p->unitx, p->unity, lat, lon);
-            g_ascii_formatd(strlat, 32, "%.06f", lat);
-            g_ascii_formatd(strlon, 32, "%.06f", lon);
-            snprintf(buffer, sizeof(buffer), "%s, %s", strlat, strlon);
-            from = buffer;
-        }
-        else
-        {
-            from = gtk_entry_get_text(GTK_ENTRY(oti.txt_from));
-        }
-
-        if(!strlen(from))
-        {
-            popup_error(dialog, _("Please specify a start location."));
-            continue;
-        }
-
-        to = gtk_entry_get_text(GTK_ENTRY(oti.txt_to));
-        if(!strlen(to))
-        {
-            popup_error(dialog, _("Please specify an end location."));
-            continue;
-        }
-
-        from_escaped = gnome_vfs_escape_string(from);
-        to_escaped = gnome_vfs_escape_string(to);
-        buffer = g_strdup_printf(source_url, from_escaped, to_escaped);
-        g_free(from_escaped);
-        g_free(to_escaped);
-
-        if(gtk_toggle_button_get_active(
-                    GTK_TOGGLE_BUTTON(oti.chk_avoid_highways)))
-        {
-            gchar *old = buffer;
-            buffer = g_strconcat(old, "&avoid_highways=on", NULL);
-            g_free(old);
-        }
-
-        /* Attempt to download the route from the server. */
-        MACRO_CURL_EASY_INIT(curl_easy);
-        curl_easy_setopt(curl_easy, CURLOPT_URL, buffer);
-        curl_easy_setopt(curl_easy, CURLOPT_WRITEFUNCTION,
-                route_dl_cb_read);
-        curl_easy_setopt(curl_easy, CURLOPT_WRITEDATA, &rdl_data);
-        if(CURLE_OK != curl_easy_perform(curl_easy))
-        {
-            popup_error(dialog,
-                    _("Failed to connect to GPX Directions server"));
-            curl_easy_cleanup(curl_easy);
-            g_free(rdl_data.bytes);
-            /* Let them try again */
-            continue;
-        }
-        curl_easy_cleanup(curl_easy);
-        g_free(buffer);
-
-        if(strncmp(rdl_data.bytes, "<?xml", strlen("<?xml")))
-        {
-            /* Not an XML document - must be bad locations. */
-            popup_error(dialog,
-                    _("Invalid source or destination."));
-            g_free(rdl_data.bytes);
-            /* Let them try again. */
-        }
-        /* Else, if GPS is enabled, replace the route, otherwise append it. */
-        else if(parse_gpx(&_route, rdl_data.bytes, rdl_data.bytes_read,
-                    (gtk_toggle_button_get_active(
-                      GTK_TOGGLE_BUTTON(oti.rad_use_gps))
-                        ? 0 : 1)))
-        {
-            GtkTreeIter iter;
-
-            /* Find the nearest route point, if we're connected. */
-            route_find_nearest_point();
-
-            /* Cancel any autoroute that might be occurring. */
-            cancel_autoroute(FALSE);
-
-            map_force_redraw();
-
-            if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(oti.chk_auto)))
-            {
-                /* Kick off a timeout to start the first update. */
-                _autoroute_data.dest = gnome_vfs_escape_string(to);
-                _autoroute_data.enabled = TRUE;
-            }
-
-            /* Save Origin in Route Locations list if not from GPS. */
-            if(gtk_toggle_button_get_active(
-                        GTK_TOGGLE_BUTTON(oti.rad_use_text))
-                && !g_slist_find_custom(_loc_list, from,
-                            (GCompareFunc)strcmp))
-            {
-                _loc_list = g_slist_prepend(_loc_list, g_strdup(from));
-                gtk_list_store_insert_with_values(_loc_model, &iter,
-                        INT_MAX, 0, from, -1);
-            }
-
-            /* Save Destination in Route Locations list. */
-            if(!g_slist_find_custom(_loc_list, to,
-                        (GCompareFunc)strcmp))
-            {
-                _loc_list = g_slist_prepend(_loc_list, g_strdup(to));
-                gtk_list_store_insert_with_values(_loc_model, &iter,
-                        INT_MAX, 0, to, -1);
-            }
-
-            MACRO_BANNER_SHOW_INFO(_window, _("Route Downloaded"));
-            g_free(rdl_data.bytes);
-
-            /* Success! Get out of the while loop. */
-            break;
-        }
-        else
-        {
-            popup_error(dialog, _("Error parsing GPX file."));
-            g_free(rdl_data.bytes);
-            /* Let them try again. */
-        }
-    }
-
-    gtk_widget_hide(dialog); /* Destroying causes a crash (!?!?!??!) */
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_route_download(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-    route_download(NULL);
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_route_open(GtkAction *action)
-{
-    gchar *buffer;
-    gint size;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(open_file(&buffer, NULL, &size, &_route_dir_uri, NULL,
-                    GTK_FILE_CHOOSER_ACTION_OPEN))
-    {
-        /* If auto is enabled, append the route, otherwise replace it. */
-        if(parse_gpx(&_route, buffer, size,
-                    _autoroute_data.enabled ? 0 : 1))
-        {
-            cancel_autoroute(FALSE);
-
-            /* Find the nearest route point, if we're connected. */
-            route_find_nearest_point();
-
-            map_force_redraw();
-            MACRO_BANNER_SHOW_INFO(_window, _("Route Opened"));
-        }
-        else
-            popup_error(_window, _("Error parsing GPX file."));
-        g_free(buffer);
-    }
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_route_distnext(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    route_show_distance_to_next();
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_route_distlast(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    route_show_distance_to_last();
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_route_reset(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    route_find_nearest_point();
-    MACRO_MAP_RENDER_DATA();
-    MACRO_QUEUE_DRAW_AREA();
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_route_clear(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    cancel_autoroute(FALSE);
-    MACRO_PATH_FREE(_route);
-    MACRO_PATH_INIT(_route);
-    route_find_nearest_point();
-    map_force_redraw();
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_track_open(GtkAction *action)
-{
-    gchar *buffer;
-    gint size;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(open_file(&buffer, NULL, &size, NULL, &_track_file_uri,
-                    GTK_FILE_CHOOSER_ACTION_OPEN))
-    {
-        if(parse_gpx(&_track, buffer, size, -1))
-        {
-            map_force_redraw();
-            MACRO_BANNER_SHOW_INFO(_window, _("Track Opened"));
-        }
-        else
-            popup_error(_window, _("Error parsing GPX file."));
-        g_free(buffer);
-    }
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_track_save(GtkAction *action)
-{
-    GnomeVFSHandle *handle;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(open_file(NULL, &handle, NULL, NULL, &_track_file_uri,
-                    GTK_FILE_CHOOSER_ACTION_SAVE))
-    {
-        if(write_gpx(&_track, handle))
-        {
-            MACRO_BANNER_SHOW_INFO(_window, _("Track Saved"));
-        }
-        else
-            popup_error(_window, _("Error writing GPX file."));
-        gnome_vfs_close(handle);
-    }
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_track_insert_break(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    track_insert_break();
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_track_insert_mark(GtkAction *action)
-{
-    gfloat lat, lon;
-    gchar tmp1[LL_FMT_LEN], tmp2[LL_FMT_LEN], *p_latlon;
-    static GtkWidget *dialog = NULL;
-    static GtkWidget *table = NULL;
-    static GtkWidget *label = NULL;
-    static GtkWidget *lbl_latlon = NULL;
-    static GtkWidget *txt_scroll = NULL;
-    static GtkWidget *txt_desc = NULL;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(dialog == NULL)
-    {
-        dialog = gtk_dialog_new_with_buttons(_("Insert Mark"),
-                GTK_WINDOW(_window), GTK_DIALOG_MODAL,
-                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
-                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
-                NULL);
-
-        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
-                table = gtk_table_new(2, 2, FALSE), TRUE, TRUE, 0);
-
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("Lat, Lon:")),
-                0, 1, 0, 1, GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-
-        gtk_table_attach(GTK_TABLE(table),
-                lbl_latlon = gtk_label_new(""),
-                1, 2, 0, 1, GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(lbl_latlon), 0.0f, 0.5f);
-
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("Description")),
-                0, 1, 1, 2, GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-
-        txt_scroll = gtk_scrolled_window_new(NULL, NULL);
-        gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(txt_scroll),
-                                       GTK_SHADOW_IN);
-        gtk_table_attach(GTK_TABLE(table),
-                txt_scroll,
-                1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-
-        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(txt_scroll),
-                GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-
-        txt_desc = gtk_text_view_new ();
-        gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt_desc), GTK_WRAP_WORD);
-
-        gtk_container_add(GTK_CONTAINER(txt_scroll), txt_desc);
-        gtk_widget_set_size_request(GTK_WIDGET(txt_scroll), 400, 60);
-    }
-
-    unit2latlon(_pos.unitx, _pos.unity, lat, lon);
-    lat_format(lat, tmp1);
-    lon_format(lon, tmp2);
-    p_latlon = g_strdup_printf("%s, %s", tmp1, tmp2);
-    gtk_label_set_text(GTK_LABEL(lbl_latlon), p_latlon);
-    g_free(p_latlon);
-
-    gtk_text_buffer_set_text(
-            gtk_text_view_get_buffer(GTK_TEXT_VIEW(txt_desc)), "", 0);
-
-    gtk_widget_show_all(dialog);
-
-    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
-    {
-        GtkTextBuffer *tbuf;
-        GtkTextIter ti1, ti2;
-        gchar *desc;
-
-        tbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txt_desc));
-        gtk_text_buffer_get_iter_at_offset(tbuf, &ti1, 0);
-        gtk_text_buffer_get_end_iter(tbuf, &ti2);
-        desc = gtk_text_buffer_get_text(tbuf, &ti1, &ti2, TRUE);
-
-        if(*desc)
-        {
-            MACRO_PATH_INCREMENT_WTAIL(_track);
-            _track.wtail->point = _track.tail;
-            _track.wtail->desc
-                = gtk_text_buffer_get_text(tbuf, &ti1, &ti2, TRUE);
-        }
-        else
-        {
-            popup_error(dialog,
-                    _("Please provide a description for the mark."));
-            g_free(desc);
-            continue;
-        }
-
-        map_render_paths();
-        MACRO_QUEUE_DRAW_AREA();
-        break;
-    }
-    gtk_widget_hide(dialog);
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_track_distlast(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    track_show_distance_from_last();
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_track_distfirst(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    track_show_distance_from_first();
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_route_save(GtkAction *action)
-{
-    GnomeVFSHandle *handle;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(open_file(NULL, &handle, NULL, &_route_dir_uri, NULL,
-                    GTK_FILE_CHOOSER_ACTION_SAVE))
-    {
-        if(write_gpx(&_route, handle))
-        {
-            MACRO_BANNER_SHOW_INFO(_window, _("Route Saved"));
-        }
-        else
-            popup_error(_window, _("Error writing GPX file."));
-        gnome_vfs_close(handle);
-    }
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_track_clear(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    track_clear();
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_show_tracks(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    _show_tracks ^= TRACKS_MASK;
-    if(gtk_check_menu_item_get_active(
-                GTK_CHECK_MENU_ITEM(_menu_show_tracks_item)))
-    {
-        _show_tracks |= TRACKS_MASK;
-        map_render_paths();
-        MACRO_QUEUE_DRAW_AREA();
-        MACRO_BANNER_SHOW_INFO(_window, _("Tracks are now shown"));
-    }
-    else
-    {
-        _show_tracks &= ~TRACKS_MASK;
-        map_force_redraw();
-        MACRO_BANNER_SHOW_INFO(_window, _("Tracks are now hidden"));
-    }
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_show_zoomlevel(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    _show_zoomlevel = gtk_check_menu_item_get_active(
-                GTK_CHECK_MENU_ITEM(_menu_show_zoomlevel_item));
-    map_cb_configure(0, 0); /* ugly but works in this case */
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_show_scale(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    _show_scale = gtk_check_menu_item_get_active(
-                GTK_CHECK_MENU_ITEM(_menu_show_scale_item));
-    map_cb_configure(0, 0); /* ugly but works in this case */
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_show_routes(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(gtk_check_menu_item_get_active(
-                GTK_CHECK_MENU_ITEM(_menu_show_routes_item)))
-    {
-        _show_tracks |= ROUTES_MASK;
-        map_render_paths();
-        MACRO_QUEUE_DRAW_AREA();
-        MACRO_BANNER_SHOW_INFO(_window, _("Routes are now shown"));
-    }
-    else
-    {
-        _show_tracks &= ~ROUTES_MASK;
-        map_force_redraw();
-        MACRO_BANNER_SHOW_INFO(_window, _("Routes are now hidden"));
-    }
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_show_velvec(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    _show_velvec = gtk_check_menu_item_get_active(
-            GTK_CHECK_MENU_ITEM(_menu_show_velvec_item));
-    map_move_mark();
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_show_poi(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    _show_poi = gtk_check_menu_item_get_active(
-            GTK_CHECK_MENU_ITEM(_menu_show_poi_item));
-    map_force_redraw();
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_gps_show_info(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    _gps_info = gtk_check_menu_item_get_active(
-                GTK_CHECK_MENU_ITEM(_menu_gps_show_info_item));
-
-    gps_show_info();
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_ac_lead(GtkAction *action)
-{
-    guint new_center_unitx, new_center_unity;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    _center_mode = CENTER_LEAD;
-    MACRO_BANNER_SHOW_INFO(_window, _("Auto-Center Mode: Lead"));
-    MACRO_RECALC_CENTER(new_center_unitx, new_center_unity);
-    map_center_unit(new_center_unitx, new_center_unity);
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_ac_latlon(GtkAction *action)
-{
-    guint new_center_unitx, new_center_unity;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    _center_mode = CENTER_LATLON;
-    MACRO_BANNER_SHOW_INFO(_window, _("Auto-Center Mode: Lat/Lon"));
-    MACRO_RECALC_CENTER(new_center_unitx, new_center_unity);
-    map_center_unit(new_center_unitx, new_center_unity);
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_ac_none(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    _center_mode = -_center_mode;
-    MACRO_BANNER_SHOW_INFO(_window, _("Auto-Center Off"));
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_goto_latlon(GtkAction *action)
-{
-    static GtkWidget *dialog = NULL;
-    static GtkWidget *table = NULL;
-    static GtkWidget *label = NULL;
-    static GtkWidget *txt_lat = NULL;
-    static GtkWidget *txt_lon = NULL;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(dialog == NULL)
-    {
-        dialog = gtk_dialog_new_with_buttons(_("Go to Lat/Lon"),
-                GTK_WINDOW(_window), GTK_DIALOG_MODAL,
-                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
-                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
-                NULL);
-
-        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
-                table = gtk_table_new(2, 3, FALSE), TRUE, TRUE, 0);
-
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("Latitude")),
-                0, 1, 0, 1, GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-
-        gtk_table_attach(GTK_TABLE(table),
-                txt_lat = gtk_entry_new(),
-                1, 2, 0, 1, GTK_FILL, 0, 2, 4);
-        gtk_entry_set_width_chars(GTK_ENTRY(txt_lat), 16);
-        gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
-        g_object_set(G_OBJECT(txt_lat), HILDON_INPUT_MODE_HINT,
-                HILDON_INPUT_MODE_HINT_ALPHANUMERICSPECIAL, NULL);
-
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("Longitude")),
-                0, 1, 1, 2, GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-
-        gtk_table_attach(GTK_TABLE(table),
-                txt_lon = gtk_entry_new(),
-                1, 2, 1, 2, GTK_FILL, 0, 2, 4);
-        gtk_entry_set_width_chars(GTK_ENTRY(txt_lon), 16);
-        gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
-        g_object_set(G_OBJECT(txt_lon), HILDON_INPUT_MODE_HINT,
-                HILDON_INPUT_MODE_HINT_ALPHANUMERICSPECIAL, NULL);
-    }
-
-    /* Initialize with the current center position. */
-    {
-        gchar buffer[32];
-        gfloat lat, lon;
-        unit2latlon(_center.unitx, _center.unity, lat, lon);
-        lat_format(lat, buffer);
-        gtk_entry_set_text(GTK_ENTRY(txt_lat), buffer);
-        lon_format(lon, buffer);
-        gtk_entry_set_text(GTK_ENTRY(txt_lon), buffer);
-    }
-
-    gtk_widget_show_all(dialog);
-
-    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
-    {
-        const gchar *text;
-        gchar *error_check;
-        gdouble lat, lon;
-        guint unitx, unity;
-
-        text = gtk_entry_get_text(GTK_ENTRY(txt_lat));
-        lat = strdmstod(text, &error_check);
-        if(text == error_check || lat < -90. || lat > 90.) {
-            popup_error(dialog, _("Invalid Latitude"));
-            continue;
-        }
-
-        text = gtk_entry_get_text(GTK_ENTRY(txt_lon));
-        lon = strdmstod(text, &error_check);
-        if(text == error_check || lon < -180. || lon > 180.) {
-            popup_error(dialog, _("Invalid Longitude"));
-            continue;
-        }
-
-        latlon2unit(lat, lon, unitx, unity);
-        if(_center_mode > 0)
-            gtk_check_menu_item_set_active(
-                    GTK_CHECK_MENU_ITEM(_menu_ac_none_item), TRUE);
-        map_center_unit(unitx, unity);
-        break;
-    }
-    gtk_widget_hide(dialog);
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_goto_address(GtkAction *action)
-{
-    static GtkWidget *dialog = NULL;
-    static GtkWidget *table = NULL;
-    static GtkWidget *label = NULL;
-    static GtkWidget *txt_addr = NULL;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(dialog == NULL)
-    {
-        GtkEntryCompletion *comp;
-        dialog = gtk_dialog_new_with_buttons(_("Go to Address"),
-                GTK_WINDOW(_window), GTK_DIALOG_MODAL,
-                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
-                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
-                NULL);
-
-        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
-                table = gtk_table_new(2, 3, FALSE), TRUE, TRUE, 0);
-
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("Address")),
-                0, 1, 0, 1, GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-
-        gtk_table_attach(GTK_TABLE(table),
-                txt_addr = gtk_entry_new(),
-                1, 2, 0, 1, GTK_FILL, 0, 2, 4);
-        gtk_entry_set_width_chars(GTK_ENTRY(txt_addr), 25);
-        gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
-
-        /* Set up auto-completion. */
-        comp = gtk_entry_completion_new();
-        gtk_entry_completion_set_model(comp, GTK_TREE_MODEL(_loc_model));
-        gtk_entry_completion_set_text_column(comp, 0);
-        gtk_entry_set_completion(GTK_ENTRY(txt_addr), comp);
-    }
-
-    gtk_widget_show_all(dialog);
-
-    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
-    {
-        Path temp;
-        RouteDownloadData rdl_data = {0, 0};
-        CURL *curl_easy;
-        const gchar *addr;
-        gchar *addr_escaped;
-        gchar *buffer;
-
-        addr = gtk_entry_get_text(GTK_ENTRY(txt_addr));
-        if(!strlen(addr))
-        {
-            popup_error(dialog, _("Please specify an address."));
-            continue;
-        }
-        addr_escaped = gnome_vfs_escape_string(addr);
-        buffer = g_strdup_printf(_route_dl_url, addr_escaped, addr_escaped);
-        g_free(addr_escaped);
-
-        /* Attempt to download the route from the server. */
-        MACRO_CURL_EASY_INIT(curl_easy);
-        curl_easy_setopt(curl_easy, CURLOPT_URL, buffer);
-        curl_easy_setopt(curl_easy, CURLOPT_WRITEFUNCTION,
-                route_dl_cb_read);
-        curl_easy_setopt(curl_easy, CURLOPT_WRITEDATA, &rdl_data);
-        if(CURLE_OK != curl_easy_perform(curl_easy))
-        {
-            popup_error(dialog,
-                    _("Failed to connect to GPX Directions server"));
-            curl_easy_cleanup(curl_easy);
-            g_free(rdl_data.bytes);
-            /* Let them try again */
-            continue;
-        }
-        curl_easy_cleanup(curl_easy);
-        g_free(buffer);
-
-        MACRO_PATH_INIT(temp);
-        if(strncmp(rdl_data.bytes, "<?xml", strlen("<?xml")))
-        {
-            /* Not an XML document - must be bad locations. */
-            popup_error(dialog,
-                    _("Invalid address."));
-            /* Let them try again. */
-        }
-        else if(parse_gpx(&temp, rdl_data.bytes, rdl_data.bytes_read, 0)
-                && temp.head[1].unity)
-        {
-            /* Save Destination in Route Locations list. */
-            GtkTreeIter iter;
-            if(!g_slist_find_custom(_loc_list, addr,
-                        (GCompareFunc)strcmp))
-            {
-                _loc_list = g_slist_prepend(_loc_list, g_strdup(addr));
-                gtk_list_store_insert_with_values(_loc_model, &iter,
-                        INT_MAX, 0, addr, -1);
-            }
-
-            MACRO_BANNER_SHOW_INFO(_window, _("Address Located"));
-
-            if(_center_mode > 0)
-                gtk_check_menu_item_set_active(
-                        GTK_CHECK_MENU_ITEM(_menu_ac_none_item), TRUE);
-
-            map_center_unit(temp.head[1].unitx, temp.head[1].unity);
-
-            MACRO_PATH_FREE(temp);
-            g_free(rdl_data.bytes);
-
-            /* Success! Get out of the while loop. */
-            break;
-        }
-        else
-        {
-            popup_error(dialog, _("Unknown error while locating address."));
-            /* Let them try again. */
-        }
-        MACRO_PATH_FREE(temp);
-        g_free(rdl_data.bytes);
-    }
-    gtk_widget_hide(dialog);
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_goto_gps(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(_center_mode > 0)
-        gtk_check_menu_item_set_active(
-                GTK_CHECK_MENU_ITEM(_menu_ac_none_item), TRUE);
-
-    map_center_unit(_pos.unitx, _pos.unity);
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_goto_nextway(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(_next_way && _next_way->point->unity)
-    {
-        if(_center_mode > 0)
-            gtk_check_menu_item_set_active(
-                    GTK_CHECK_MENU_ITEM(_menu_ac_none_item), TRUE);
-
-        map_center_unit(_next_way->point->unitx, _next_way->point->unity);
-    }
-    else
-    {
-        MACRO_BANNER_SHOW_INFO(_window, _("There is no next waypoint."));
-    }
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_goto_nearpoi(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(_db)
-    {
-        PoiInfo poi;
-        gchar *banner;
-        guint unitx, unity;
-
-        if((_center_mode > 0 ? get_nearest_poi(_pos.unitx, _pos.unity, &poi)
-                    : get_nearest_poi(_center.unitx, _center.unity, &poi) ))
-        {
-            /* Auto-Center is enabled - use the GPS position. */
-            latlon2unit(poi.lat, poi.lon, unitx, unity);
-            banner = g_strdup_printf("%s (%s)", poi.label, poi.clabel);
-            MACRO_BANNER_SHOW_INFO(_window, banner);
-            g_free(banner);
-            g_free(poi.label);
-            g_free(poi.desc);
-            g_free(poi.clabel);
-
-            if(_center_mode > 0)
-                gtk_check_menu_item_set_active(
-                        GTK_CHECK_MENU_ITEM(_menu_ac_none_item), TRUE);
-
-            map_center_unit(unitx, unity);
-        }
-        else
-        {
-            MACRO_BANNER_SHOW_INFO(_window, _("No POIs found."));
-            /* Auto-Center is disabled - use the view center. */
-        }
-    }
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-typedef struct _RepoManInfo RepoManInfo;
-struct _RepoManInfo {
-    GtkWidget *dialog;
-    GtkWidget *notebook;
-    GtkWidget *cmb_repos;
-    GList *repo_edits;
-};
-
-typedef struct _RepoEditInfo RepoEditInfo;
-struct _RepoEditInfo {
-    gchar *name;
-    GtkWidget *txt_url;
-    GtkWidget *txt_cache_dir;
-    GtkWidget *num_dl_zoom_steps;
-    GtkWidget *num_view_zoom_steps;
-    GtkWidget *chk_double_size;
-    GtkWidget *chk_nextable;
-    GtkWidget *btn_browse;
-    BrowseInfo browse_info;
-};
-
-static gboolean
-repoman_dialog_select(GtkWidget *widget, RepoManInfo *rmi)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-    gint curr_index = gtk_combo_box_get_active(GTK_COMBO_BOX(rmi->cmb_repos));
-    gtk_notebook_set_current_page(GTK_NOTEBOOK(rmi->notebook), curr_index);
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-repoman_dialog_browse(GtkWidget *widget, BrowseInfo *browse_info)
-{
-    GtkWidget *dialog;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    dialog = GTK_WIDGET(
-            hildon_file_chooser_dialog_new(GTK_WINDOW(browse_info->dialog),
-            GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER));
-
-    gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(dialog), TRUE);
-    gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),
-            gtk_entry_get_text(GTK_ENTRY(browse_info->txt)));
-
-    if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(dialog)))
-    {
-        gchar *filename = gtk_file_chooser_get_filename(
-                GTK_FILE_CHOOSER(dialog));
-        gtk_entry_set_text(GTK_ENTRY(browse_info->txt), filename);
-        g_free(filename);
-    }
-
-    gtk_widget_destroy(dialog);
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-repoman_dialog_rename(GtkWidget *widget, RepoManInfo *rmi)
-{
-    static GtkWidget *hbox = NULL;
-    static GtkWidget *label = NULL;
-    static GtkWidget *txt_name = NULL;
-    static GtkWidget *dialog = NULL;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(dialog == NULL)
-    {
-        dialog = gtk_dialog_new_with_buttons(_("New Name"),
-                GTK_WINDOW(rmi->dialog), GTK_DIALOG_MODAL,
-                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
-                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
-                NULL);
-
-        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
-                hbox = gtk_hbox_new(FALSE, 4), FALSE, FALSE, 4);
-
-        gtk_box_pack_start(GTK_BOX(hbox),
-                label = gtk_label_new(_("Name")),
-                FALSE, FALSE, 0);
-        gtk_box_pack_start(GTK_BOX(hbox),
-                txt_name = gtk_entry_new(),
-                TRUE, TRUE, 0);
-    }
-
-    {
-        gint active = gtk_combo_box_get_active(GTK_COMBO_BOX(rmi->cmb_repos));
-        RepoEditInfo *rei = g_list_nth_data(rmi->repo_edits, active);
-        gtk_entry_set_text(GTK_ENTRY(txt_name), rei->name);
-    }
-
-    gtk_widget_show_all(dialog);
-
-    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
-    {
-        gint active = gtk_combo_box_get_active(GTK_COMBO_BOX(rmi->cmb_repos));
-        RepoEditInfo *rei = g_list_nth_data(rmi->repo_edits, active);
-        g_free(rei->name);
-        rei->name = g_strdup(gtk_entry_get_text(GTK_ENTRY(txt_name)));
-        gtk_combo_box_insert_text(GTK_COMBO_BOX(rmi->cmb_repos),
-                active, g_strdup(rei->name));
-        gtk_combo_box_set_active(GTK_COMBO_BOX(rmi->cmb_repos), active);
-        gtk_combo_box_remove_text(GTK_COMBO_BOX(rmi->cmb_repos), active + 1);
-        break;
-    }
-
-    gtk_widget_hide(dialog);
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static void
-repoman_delete(RepoManInfo *rmi, gint index)
-{
-    gtk_combo_box_remove_text(GTK_COMBO_BOX(rmi->cmb_repos), index);
-    gtk_notebook_remove_page(GTK_NOTEBOOK(rmi->notebook), index);
-    rmi->repo_edits = g_list_remove_link(
-            rmi->repo_edits,
-            g_list_nth(rmi->repo_edits, index));
-}
-
-static gboolean
-repoman_dialog_delete(GtkWidget *widget, RepoManInfo *rmi)
-{
-    gchar buffer[100];
-    GtkWidget *confirm;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(gtk_tree_model_iter_n_children(GTK_TREE_MODEL(
-                    gtk_combo_box_get_model(GTK_COMBO_BOX(rmi->cmb_repos))),
-                                NULL) <= 1)
-    {
-        popup_error(rmi->dialog,
-                _("Cannot delete the last repository - there must be at"
-                " lease one repository."));
-        vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-        return TRUE;
-    }
-
-    snprintf(buffer, sizeof(buffer), "%s:\n%s\n",
-            _("Confirm delete of repository"),
-            gtk_combo_box_get_active_text(GTK_COMBO_BOX(rmi->cmb_repos)));
-
-    confirm = hildon_note_new_confirmation(GTK_WINDOW(rmi->dialog),buffer);
-
-    if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm)))
-    {
-        gint active = gtk_combo_box_get_active(GTK_COMBO_BOX(rmi->cmb_repos));
-        repoman_delete(rmi, active);
-        gtk_combo_box_set_active(GTK_COMBO_BOX(rmi->cmb_repos),
-                MAX(0, active - 1));
-    }
-
-    gtk_widget_destroy(confirm);
-
-    return TRUE;
-}
-
-static RepoEditInfo*
-repoman_dialog_add_repo(RepoManInfo *rmi, gchar *name)
-{
-    GtkWidget *vbox;
-    GtkWidget *table;
-    GtkWidget *label;
-    GtkWidget *hbox;
-    RepoEditInfo *rei = g_new(RepoEditInfo, 1);
-    printf("%s(%s)\n", __PRETTY_FUNCTION__, name);
-
-    rei->name = name;
-
-    /* Maps page. */
-    gtk_notebook_append_page(GTK_NOTEBOOK(rmi->notebook),
-            vbox = gtk_vbox_new(FALSE, 4),
-            gtk_label_new(name));
-
-    /* Prevent destruction of notebook page, because the destruction causes
-     * a seg fault (!?!?) */
-    gtk_object_ref(GTK_OBJECT(vbox));
-
-    gtk_box_pack_start(GTK_BOX(vbox),
-            table = gtk_table_new(2, 2, FALSE),
-            FALSE, FALSE, 0);
-    /* Map download URI. */
-    gtk_table_attach(GTK_TABLE(table),
-            label = gtk_label_new(_("URL Format")),
-            0, 1, 0, 1, GTK_FILL, 0, 2, 4);
-    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-    gtk_table_attach(GTK_TABLE(table),
-            rei->txt_url = gtk_entry_new(),
-            1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-
-    /* Map Directory. */
-    gtk_table_attach(GTK_TABLE(table),
-            label = gtk_label_new(_("Cache Dir.")),
-            0, 1, 1, 2, GTK_FILL, 0, 2, 4);
-    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-    gtk_table_attach(GTK_TABLE(table),
-            hbox = gtk_hbox_new(FALSE, 4),
-            1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-    gtk_box_pack_start(GTK_BOX(hbox),
-            rei->txt_cache_dir = gtk_entry_new(),
-            TRUE, TRUE, 0);
-    gtk_box_pack_start(GTK_BOX(hbox),
-            rei->btn_browse = gtk_button_new_with_label(_("Browse...")),
-            FALSE, FALSE, 0);
-
-    /* Initialize cache dir */
-    {
-        gchar *cache_base = gnome_vfs_expand_initial_tilde(
-                REPO_DEFAULT_CACHE_BASE);
-        gchar *cache_dir = gnome_vfs_uri_make_full_from_relative(
-                cache_base, name);
-        gtk_entry_set_text(GTK_ENTRY(rei->txt_cache_dir), cache_dir);
-        g_free(cache_dir);
-        g_free(cache_base);
-    }
-
-    gtk_box_pack_start(GTK_BOX(vbox),
-            table = gtk_table_new(3, 2, FALSE),
-            FALSE, FALSE, 0);
-
-    /* Download Zoom Steps. */
-    gtk_table_attach(GTK_TABLE(table),
-            label = gtk_label_new(_("Download Zoom Steps")),
-            0, 1, 0, 1, GTK_FILL, 0, 2, 4);
-    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-    gtk_table_attach(GTK_TABLE(table),
-            label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
-            1, 2, 0, 1, GTK_FILL, 0, 2, 4);
-    gtk_container_add(GTK_CONTAINER(label),
-            rei->num_dl_zoom_steps = hildon_controlbar_new());
-    hildon_controlbar_set_range(
-            HILDON_CONTROLBAR(rei->num_dl_zoom_steps), 1, 4);
-    hildon_controlbar_set_value(HILDON_CONTROLBAR(rei->num_dl_zoom_steps),
-            REPO_DEFAULT_DL_ZOOM_STEPS);
-    force_min_visible_bars(HILDON_CONTROLBAR(rei->num_dl_zoom_steps), 1);
-
-    /* Download Zoom Steps. */
-    gtk_table_attach(GTK_TABLE(table),
-            label = gtk_label_new(_("View Zoom Steps")),
-            0, 1, 1, 2, GTK_FILL, 0, 2, 4);
-    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-    gtk_table_attach(GTK_TABLE(table),
-            label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
-            1, 2, 1, 2, GTK_FILL, 0, 2, 4);
-    gtk_container_add(GTK_CONTAINER(label),
-            rei->num_view_zoom_steps = hildon_controlbar_new());
-    hildon_controlbar_set_range(
-            HILDON_CONTROLBAR(rei->num_view_zoom_steps), 1, 4);
-    hildon_controlbar_set_value(HILDON_CONTROLBAR(rei->num_view_zoom_steps),
-            REPO_DEFAULT_VIEW_ZOOM_STEPS);
-    force_min_visible_bars(HILDON_CONTROLBAR(rei->num_view_zoom_steps), 1);
-
-    gtk_table_attach(GTK_TABLE(table),
-            label = gtk_vseparator_new(),
-            2, 3, 0, 2, GTK_FILL, GTK_FILL, 4, 4);
-
-    /* Double-size. */
-    gtk_table_attach(GTK_TABLE(table),
-            rei->chk_double_size = gtk_check_button_new_with_label(
-                _("Double Pixels")),
-            3, 4, 0, 1, GTK_FILL, GTK_FILL, 0, 4);
-    gtk_toggle_button_set_active(
-            GTK_TOGGLE_BUTTON(rei->chk_double_size), FALSE);
-
-    /* Next-able */
-    gtk_table_attach(GTK_TABLE(table),
-            rei->chk_nextable = gtk_check_button_new_with_label(
-                _("Next-able")),
-            3, 4, 1, 2, GTK_FILL, GTK_FILL, 0, 4);
-    gtk_toggle_button_set_active(
-            GTK_TOGGLE_BUTTON(rei->chk_nextable), TRUE);
-
-    rmi->repo_edits = g_list_append(rmi->repo_edits, rei);
-
-    /* Connect signals. */
-    rei->browse_info.dialog = rmi->dialog;
-    rei->browse_info.txt = rei->txt_cache_dir;
-    g_signal_connect(G_OBJECT(rei->btn_browse), "clicked",
-                      G_CALLBACK(repoman_dialog_browse),
-                      &rei->browse_info);
-
-    gtk_widget_show_all(vbox);
-
-    gtk_combo_box_append_text(GTK_COMBO_BOX(rmi->cmb_repos), name);
-    gtk_combo_box_set_active(GTK_COMBO_BOX(rmi->cmb_repos),
-            gtk_tree_model_iter_n_children(GTK_TREE_MODEL(
-                    gtk_combo_box_get_model(GTK_COMBO_BOX(rmi->cmb_repos))),
-                NULL) - 1);
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return rei;
-}
-
-static gboolean
-repoman_dialog_new(GtkWidget *widget, RepoManInfo *rmi)
-{
-    static GtkWidget *hbox = NULL;
-    static GtkWidget *label = NULL;
-    static GtkWidget *txt_name = NULL;
-    static GtkWidget *dialog = NULL;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(dialog == NULL)
-    {
-        dialog = gtk_dialog_new_with_buttons(_("New Repository"),
-                GTK_WINDOW(rmi->dialog), GTK_DIALOG_MODAL,
-                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
-                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
-                NULL);
-
-        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
-                hbox = gtk_hbox_new(FALSE, 4), FALSE, FALSE, 4);
-
-        gtk_box_pack_start(GTK_BOX(hbox),
-                label = gtk_label_new(_("Name")),
-                FALSE, FALSE, 0);
-        gtk_box_pack_start(GTK_BOX(hbox),
-                txt_name = gtk_entry_new(),
-                TRUE, TRUE, 0);
-    }
-
-    gtk_entry_set_text(GTK_ENTRY(txt_name), "");
-
-    gtk_widget_show_all(dialog);
-
-    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
-    {
-        repoman_dialog_add_repo(rmi,
-                g_strdup(gtk_entry_get_text(GTK_ENTRY(txt_name))));
-        break;
-    }
-
-    gtk_widget_hide(dialog);
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-repoman_reset(GtkWidget *widget, RepoManInfo *rmi)
-{
-    GtkWidget *confirm;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    confirm = hildon_note_new_confirmation(GTK_WINDOW(rmi->dialog),
-            _("Replace all repositories with the default repository?"));
-
-    if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm)))
-    {
-        /* First, delete all existing repositories. */
-        while(rmi->repo_edits)
-            repoman_delete(rmi, 0);
-
-        /* Now, add the default repository. */
-        repoman_dialog_add_repo(rmi, REPO_DEFAULT_NAME);
-        gtk_entry_set_text(
-                GTK_ENTRY(((RepoEditInfo*)rmi->repo_edits->data)->txt_url),
-                REPO_DEFAULT_MAP_URI);
-
-        gtk_combo_box_set_active(GTK_COMBO_BOX(rmi->cmb_repos), 0);
-    }
-    gtk_widget_destroy(confirm);
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-repoman_download(GtkWidget *widget, RepoManInfo *rmi)
-{
-    GtkWidget *confirm;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    confirm = hildon_note_new_confirmation(
-            GTK_WINDOW(rmi->dialog),
-            _("Maemo Mapper will now download and add a list of "
-                "possibly-duplicate repositories from the internet.  "
-                "Continue?"));
-
-    if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm)))
-    {
-        gchar *bytes;
-        gchar *head;
-        gchar *tail;
-        gint size;
-        GnomeVFSResult vfs_result;
-        printf("%s()\n", __PRETTY_FUNCTION__);
-
-        /* Get repo config file from www.gnuite.com. */
-        if(GNOME_VFS_OK != (vfs_result = gnome_vfs_read_entire_file(
-                    "http://www.gnuite.com/nokia770/maemo-mapper/repos.txt",
-                    &size, &bytes)))
-        {
-            popup_error(rmi->dialog,
-                    _("An error occurred while retrieving the repositories.  "
-                        "The web service may be temporarily down."));
-            g_printerr("Error while download repositories: %s\n",
-                    gnome_vfs_result_to_string(vfs_result));
-        }
-        /* Parse each line as a reposotory. */
-        else
-        {
-            for(head = bytes; head && *head; head = tail)
-            {
-                RepoData *rd;
-                RepoEditInfo *rei;
-                tail = strchr(head, '\n');
-                *tail++ = '\0';
-                rd = config_parse_repo(head);
-                rei = repoman_dialog_add_repo(
-                        rmi, g_strdup(rd->name));
-                /* Initialize fields with data from the RepoData object. */
-                gtk_entry_set_text(GTK_ENTRY(rei->txt_url), rd->url);
-                gtk_entry_set_text(GTK_ENTRY(rei->txt_cache_dir),
-                        rd->cache_dir);
-                hildon_controlbar_set_value(
-                        HILDON_CONTROLBAR(rei->num_dl_zoom_steps),
-                        rd->dl_zoom_steps);
-                hildon_controlbar_set_value(
-                        HILDON_CONTROLBAR(rei->num_view_zoom_steps),
-                        rd->view_zoom_steps);
-                gtk_toggle_button_set_active(
-                        GTK_TOGGLE_BUTTON(rei->chk_double_size),
-                        rd->double_size);
-                gtk_toggle_button_set_active(
-                        GTK_TOGGLE_BUTTON(rei->chk_nextable),
-                        rd->nextable);
-            }
-            g_free(bytes);
-        }
-    }
-    gtk_widget_destroy(confirm);
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-repoman_dialog()
-{
-    static RepoManInfo rmi;
-    static GtkWidget *dialog = NULL;
-    static GtkWidget *hbox = NULL;
-    static GtkWidget *btn_rename = NULL;
-    static GtkWidget *btn_delete = NULL;
-    static GtkWidget *btn_new = NULL;
-    static GtkWidget *btn_reset = NULL;
-    static GtkWidget *btn_download = NULL;
-    guint i, curr_repo_index = 0;
-    GList *curr;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(dialog == NULL)
-    {
-        rmi.dialog = dialog = gtk_dialog_new_with_buttons(
-                _("Manage Repositories"),
-                GTK_WINDOW(_window), GTK_DIALOG_MODAL,
-                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
-                NULL);
-
-        /* Enable the help button. */
-        ossohelp_dialog_help_enable(
-                GTK_DIALOG(dialog), HELP_ID_REPOMAN, _osso);
-
-        /* Reset button. */
-        gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
-                btn_reset = gtk_button_new_with_label(_("Reset...")));
-        g_signal_connect(G_OBJECT(btn_reset), "clicked",
-                          G_CALLBACK(repoman_reset), &rmi);
-
-        /* Download button. */
-        gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
-                btn_download = gtk_button_new_with_label(_("Download...")));
-        g_signal_connect(G_OBJECT(btn_download), "clicked",
-                          G_CALLBACK(repoman_download), &rmi);
-
-        /* Cancel button. */
-        gtk_dialog_add_button(GTK_DIALOG(dialog),
-                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
-
-        hbox = gtk_hbox_new(FALSE, 4);
-
-        gtk_box_pack_start(GTK_BOX(hbox),
-                rmi.cmb_repos = gtk_combo_box_new_text(), TRUE, TRUE, 4);
-
-        gtk_box_pack_start(GTK_BOX(hbox),
-                gtk_vseparator_new(), FALSE, FALSE, 4);
-        gtk_box_pack_start(GTK_BOX(hbox),
-                btn_rename = gtk_button_new_with_label(_("Rename...")),
-                FALSE, FALSE, 4);
-        gtk_box_pack_start(GTK_BOX(hbox),
-                btn_delete = gtk_button_new_with_label(_("Delete...")),
-                FALSE, FALSE, 4);
-        gtk_box_pack_start(GTK_BOX(hbox),
-                btn_new = gtk_button_new_with_label(_("New...")),
-                FALSE, FALSE, 4);
-
-        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
-                hbox, FALSE, FALSE, 4);
-
-        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
-                gtk_hseparator_new(), TRUE, TRUE, 4);
-        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
-                rmi.notebook = gtk_notebook_new(), TRUE, TRUE, 4);
-
-        gtk_notebook_set_show_tabs(GTK_NOTEBOOK(rmi.notebook), FALSE);
-        gtk_notebook_set_show_border(GTK_NOTEBOOK(rmi.notebook), FALSE);
-
-        rmi.repo_edits = NULL;
-
-        /* Connect signals. */
-        g_signal_connect(G_OBJECT(btn_rename), "clicked",
-                G_CALLBACK(repoman_dialog_rename), &rmi);
-        g_signal_connect(G_OBJECT(btn_delete), "clicked",
-                G_CALLBACK(repoman_dialog_delete), &rmi);
-        g_signal_connect(G_OBJECT(btn_new), "clicked",
-                G_CALLBACK(repoman_dialog_new), &rmi);
-        g_signal_connect(G_OBJECT(rmi.cmb_repos), "changed",
-                G_CALLBACK(repoman_dialog_select), &rmi);
-    }
-
-    /* Populate combo box and pages in notebook. */
-    for(i = 0, curr = _repo_list; curr; curr = curr->next, i++)
-    {
-        RepoData *rd = (RepoData*)curr->data;
-        RepoEditInfo *rei = repoman_dialog_add_repo(&rmi, g_strdup(rd->name));
-
-        /* Initialize fields with data from the RepoData object. */
-        gtk_entry_set_text(GTK_ENTRY(rei->txt_url), rd->url);
-        gtk_entry_set_text(GTK_ENTRY(rei->txt_cache_dir),
-                rd->cache_dir);
-        hildon_controlbar_set_value(
-                HILDON_CONTROLBAR(rei->num_dl_zoom_steps),
-                rd->dl_zoom_steps);
-        hildon_controlbar_set_value(
-                HILDON_CONTROLBAR(rei->num_view_zoom_steps),
-                rd->view_zoom_steps);
-        gtk_toggle_button_set_active(
-                GTK_TOGGLE_BUTTON(rei->chk_double_size),
-                rd->double_size);
-        gtk_toggle_button_set_active(
-                GTK_TOGGLE_BUTTON(rei->chk_nextable),
-                rd->nextable);
-        if(rd == _curr_repo)
-            curr_repo_index = i;
-    }
-
-    gtk_combo_box_set_active(GTK_COMBO_BOX(rmi.cmb_repos), curr_repo_index);
-    gtk_notebook_set_current_page(GTK_NOTEBOOK(rmi.notebook), curr_repo_index);
-
-    gtk_widget_show_all(dialog);
-
-    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
-    {
-        /* Iterate through repos and verify each. */
-        gboolean verified = TRUE;
-        gint i;
-        GList *curr;
-        gchar *old_curr_repo_name = _curr_repo->name;
-        for(i = 0, curr = rmi.repo_edits;
-                verified && curr; curr = curr->next, i++)
-        {
-            RepoEditInfo *rei = curr->data;
-            gchar *expanded = gnome_vfs_expand_initial_tilde(
-                    gtk_entry_get_text(GTK_ENTRY(rei->txt_cache_dir)));
-            verified = repo_make_cache_dir(rei->name, expanded, dialog);
-            g_free(expanded);
-        }
-        if(!verified)
-        {
-            gtk_combo_box_set_active(GTK_COMBO_BOX(rmi.cmb_repos), i - 1);
-            continue;
-        }
-
-        /* We're good to replace.  Remove old _repo_list menu items. */
-        menu_maps_remove_repos();
-        /* But keep the repo list in memory, in case downloads are using it. */
-        _repo_list = NULL;
-
-        /* Write new _repo_list. */
-        curr_repo_index = gtk_combo_box_get_active(
-                GTK_COMBO_BOX(rmi.cmb_repos));
-        _curr_repo = NULL;
-        for(i = 0, curr = rmi.repo_edits; curr; curr = curr->next, i++)
-        {
-            RepoEditInfo *rei = curr->data;
-            RepoData *rd = g_new(RepoData, 1);
-            rd->name = g_strdup(rei->name);
-            rd->url = g_strdup(gtk_entry_get_text(GTK_ENTRY(rei->txt_url)));
-            rd->cache_dir = gnome_vfs_expand_initial_tilde(
-                    gtk_entry_get_text(GTK_ENTRY(rei->txt_cache_dir)));
-            rd->dl_zoom_steps = hildon_controlbar_get_value(
-                    HILDON_CONTROLBAR(rei->num_dl_zoom_steps));
-            rd->view_zoom_steps = hildon_controlbar_get_value(
-                    HILDON_CONTROLBAR(rei->num_view_zoom_steps));
-            rd->double_size = gtk_toggle_button_get_active(
-                    GTK_TOGGLE_BUTTON(rei->chk_double_size));
-            rd->nextable = gtk_toggle_button_get_active(
-                    GTK_TOGGLE_BUTTON(rei->chk_nextable));
-            set_repo_type(rd);
-
-            _repo_list = g_list_append(_repo_list, rd);
-
-            if(!_curr_repo && !strcmp(old_curr_repo_name, rd->name))
-                repo_set_curr(rd);
-            else if(i == curr_repo_index)
-                repo_set_curr(rd);
-        }
-        if(!_curr_repo)
-            repo_set_curr((RepoData*)g_list_first(_repo_list)->data);
-        menu_maps_add_repos();
-
-        config_save();
-        break;
-    }
-
-    gtk_widget_hide(dialog);
-
-    /* Clear out the notebook entries. */
-    while(rmi.repo_edits)
-        repoman_delete(&rmi, 0);
-
-    map_set_zoom(_zoom); /* make sure we're at an appropriate zoom level. */
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_maps_repoman(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-    repoman_dialog();
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-typedef struct _MapmanInfo MapmanInfo;
-struct _MapmanInfo {
-    GtkWidget *dialog;
-    GtkWidget *notebook;
-    GtkWidget *tbl_area;
-
-    /* The "Setup" tab. */
-    GtkWidget *rad_download;
-    GtkWidget *rad_delete;
-    GtkWidget *chk_overwrite;
-    GtkWidget *rad_by_area;
-    GtkWidget *rad_by_route;
-    GtkWidget *num_route_radius;
-
-    /* The "Area" tab. */
-    GtkWidget *txt_topleft_lat;
-    GtkWidget *txt_topleft_lon;
-    GtkWidget *txt_botright_lat;
-    GtkWidget *txt_botright_lon;
-
-    /* The "Zoom" tab. */
-    GtkWidget *chk_zoom_levels[MAX_ZOOM];
-};
-
-static gboolean
-mapman_by_area(gfloat start_lat, gfloat start_lon,
-        gfloat end_lat, gfloat end_lon, MapmanInfo *mapman_info,
-        gboolean is_deleting, gboolean is_overwriting)
-{
-    guint start_unitx, start_unity, end_unitx, end_unity;
-    guint num_maps = 0;
-    guint i;
-    gchar buffer[80];
-    GtkWidget *confirm;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    latlon2unit(start_lat, start_lon, start_unitx, start_unity);
-    latlon2unit(end_lat, end_lon, end_unitx, end_unity);
-
-    /* Swap if they specified flipped lats or lons. */
-    if(start_unitx > end_unitx)
-    {
-        guint swap = start_unitx;
-        start_unitx = end_unitx;
-        end_unitx = swap;
-    }
-    if(start_unity > end_unity)
-    {
-        guint swap = start_unity;
-        start_unity = end_unity;
-        end_unity = swap;
-    }
-
-    /* First, get the number of maps to download. */
-    for(i = 0; i < MAX_ZOOM; i++)
-    {
-        if(gtk_toggle_button_get_active(
-                    GTK_TOGGLE_BUTTON(mapman_info->chk_zoom_levels[i])))
-        {
-            guint start_tilex, start_tiley, end_tilex, end_tiley;
-            start_tilex = unit2ztile(start_unitx, i);
-            start_tiley = unit2ztile(start_unity, i);
-            end_tilex = unit2ztile(end_unitx, i);
-            end_tiley = unit2ztile(end_unity, i);
-            num_maps += (end_tilex - start_tilex + 1)
-                * (end_tiley - start_tiley + 1);
-        }
-    }
-
-    if(is_deleting)
-    {
-        snprintf(buffer, sizeof(buffer), "%s %d %s", _("Confirm DELETION of"),
-                num_maps, _("maps "));
-    }
-    else
-    {
-        snprintf(buffer, sizeof(buffer),
-                "%s %d %s\n(%s %.2f MB)\n", _("Confirm download of"),
-                num_maps, _("maps"), _("up to about"),
-                num_maps * (strstr(_curr_repo->url, "%s") ? 18e-3 : 6e-3));
-    }
-    confirm = hildon_note_new_confirmation(
-            GTK_WINDOW(mapman_info->dialog), buffer);
-
-    if(GTK_RESPONSE_OK != gtk_dialog_run(GTK_DIALOG(confirm)))
-    {
-        gtk_widget_destroy(confirm);
-        vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
-        return FALSE;
-    }
-    for(i = 0; i < MAX_ZOOM; i++)
-    {
-        if(gtk_toggle_button_get_active(
-                    GTK_TOGGLE_BUTTON(mapman_info->chk_zoom_levels[i])))
-        {
-            guint start_tilex, start_tiley, end_tilex, end_tiley;
-            guint tilex, tiley;
-            start_tilex = unit2ztile(start_unitx, i);
-            start_tiley = unit2ztile(start_unity, i);
-            end_tilex = unit2ztile(end_unitx, i);
-            end_tiley = unit2ztile(end_unity, i);
-            for(tiley = start_tiley; tiley <= end_tiley; tiley++)
-                for(tilex = start_tilex; tilex <= end_tilex; tilex++)
-                    map_initiate_download(tilex, tiley, i,
-                            is_deleting ? 0 :
-                                      (is_overwriting
-                                        ? -INITIAL_DOWNLOAD_RETRIES
-                                        : INITIAL_DOWNLOAD_RETRIES));
-        }
-    }
-    gtk_widget_destroy(confirm);
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-mapman_by_route(MapmanInfo *mapman_info,
-        gboolean is_deleting, gboolean is_overwriting)
-{
-    GtkWidget *confirm;
-    guint prev_tilex, prev_tiley, num_maps = 0, i;
-    Point *curr;
-    gchar buffer[80];
-    guint radius = hildon_number_editor_get_value(
-            HILDON_NUMBER_EDITOR(mapman_info->num_route_radius));
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    /* First, get the number of maps to download. */
-    for(i = 0; i < MAX_ZOOM; i++)
-    {
-        if(gtk_toggle_button_get_active(
-                    GTK_TOGGLE_BUTTON(mapman_info->chk_zoom_levels[i])))
-        {
-            prev_tilex = 0;
-            prev_tiley = 0;
-            for(curr = _route.head - 1; curr++ != _route.tail; )
-            {
-                if(curr->unity)
-                {
-                    guint tilex = unit2ztile(curr->unitx, i);
-                    guint tiley = unit2ztile(curr->unity, i);
-                    if(tilex != prev_tilex || tiley != prev_tiley)
-                    {
-                        if(prev_tiley)
-                            num_maps += (abs((gint)tilex - prev_tilex) + 1)
-                                * (abs((gint)tiley - prev_tiley) + 1) - 1;
-                        prev_tilex = tilex;
-                        prev_tiley = tiley;
-                    }
-                }
-            }
-        }
-    }
-    num_maps *= 0.625 * pow(radius + 1, 1.85);
-
-    if(is_deleting)
-    {
-        snprintf(buffer, sizeof(buffer), "%s %s %d %s",
-                _("Confirm DELETION of"), _("about"),
-                num_maps, _("maps "));
-    }
-    else
-    {
-        snprintf(buffer, sizeof(buffer),
-                "%s %s %d %s\n(%s %.2f MB)\n", _("Confirm download of"),
-                _("about"),
-                num_maps, _("maps"), _("up to about"),
-                num_maps * (strstr(_curr_repo->url, "%s") ? 18e-3 : 6e-3));
-    }
-    confirm = hildon_note_new_confirmation(
-            GTK_WINDOW(mapman_info->dialog), buffer);
-
-    if(GTK_RESPONSE_OK != gtk_dialog_run(GTK_DIALOG(confirm)))
-    {
-        gtk_widget_destroy(confirm);
-        vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
-        return FALSE;
-    }
-
-    /* Now, do the actual download. */
-    for(i = 0; i < MAX_ZOOM; i++)
-    {
-        if(gtk_toggle_button_get_active(
-                    GTK_TOGGLE_BUTTON(mapman_info->chk_zoom_levels[i])))
-        {
-            prev_tilex = 0;
-            prev_tiley = 0;
-            for(curr = _route.head - 1; curr++ != _route.tail; )
-            {
-                if(curr->unity)
-                {
-                    guint tilex = unit2ztile(curr->unitx, i);
-                    guint tiley = unit2ztile(curr->unity, i);
-                    if(tilex != prev_tilex || tiley != prev_tiley)
-                    {
-                        guint minx, miny, maxx, maxy, x, y;
-                        if(prev_tiley != 0)
-                        {
-                            minx = MIN(tilex, prev_tilex) - radius;
-                            miny = MIN(tiley, prev_tiley) - radius;
-                            maxx = MAX(tilex, prev_tilex) + radius;
-                            maxy = MAX(tiley, prev_tiley) + radius;
-                        }
-                        else
-                        {
-                            minx = tilex - radius;
-                            miny = tiley - radius;
-                            maxx = tilex + radius;
-                            maxy = tiley + radius;
-                        }
-                        for(x = minx; x <= maxx; x++)
-                            for(y = miny; y <= maxy; y++)
-                                map_initiate_download(x, y, i,
-                                        is_deleting ? 0 :
-                                              (is_overwriting
-                                                ? -INITIAL_DOWNLOAD_RETRIES
-                                                : INITIAL_DOWNLOAD_RETRIES));
-                        prev_tilex = tilex;
-                        prev_tiley = tiley;
-                    }
-                }
-            }
-        }
-    }
-    _route_dl_radius = radius;
-    gtk_widget_destroy(confirm);
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static void mapman_clear(GtkWidget *widget, MapmanInfo *mapman_info)
-{
-    guint i;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-    if(gtk_notebook_get_current_page(GTK_NOTEBOOK(mapman_info->notebook)))
-        /* This is the second page (the "Zoom" page) - clear the checks. */
-        for(i = 0; i < MAX_ZOOM; i++)
-            gtk_toggle_button_set_active(
-                    GTK_TOGGLE_BUTTON(mapman_info->chk_zoom_levels[i]), FALSE);
-    else
-    {
-        /* This is the first page (the "Area" page) - clear the text fields. */
-        gtk_entry_set_text(GTK_ENTRY(mapman_info->txt_topleft_lat), "");
-        gtk_entry_set_text(GTK_ENTRY(mapman_info->txt_topleft_lon), "");
-        gtk_entry_set_text(GTK_ENTRY(mapman_info->txt_botright_lat), "");
-        gtk_entry_set_text(GTK_ENTRY(mapman_info->txt_botright_lon), "");
-    }
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static void mapman_update_state(GtkWidget *widget, MapmanInfo *mapman_info)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-    gtk_widget_set_sensitive( mapman_info->chk_overwrite,
-            gtk_toggle_button_get_active(
-                GTK_TOGGLE_BUTTON(mapman_info->rad_download)));
-
-    if(gtk_toggle_button_get_active(
-                GTK_TOGGLE_BUTTON(mapman_info->rad_by_area)))
-        gtk_widget_show(mapman_info->tbl_area);
-    else if(gtk_notebook_get_n_pages(GTK_NOTEBOOK(mapman_info->notebook)) == 3)
-        gtk_widget_hide(mapman_info->tbl_area);
-
-    gtk_widget_set_sensitive(mapman_info->num_route_radius,
-            gtk_toggle_button_get_active(
-                GTK_TOGGLE_BUTTON(mapman_info->rad_by_route)));
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static gboolean
-menu_cb_maps_select(GtkAction *action, gpointer new_repo)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-    repo_set_curr(new_repo);
-    map_force_redraw();
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_mapman(GtkAction *action)
-{
-    static GtkWidget *dialog = NULL;
-    static GtkWidget *vbox = NULL;
-    static GtkWidget *hbox = NULL;
-    static GtkWidget *table = NULL;
-    static GtkWidget *label = NULL;
-    static GtkWidget *button = NULL;
-    static GtkWidget *lbl_gps_lat = NULL;
-    static GtkWidget *lbl_gps_lon = NULL;
-    static GtkWidget *lbl_center_lat = NULL;
-    static GtkWidget *lbl_center_lon = NULL;
-    static MapmanInfo mapman_info;
-    gchar buffer[80];
-    gfloat lat, lon;
-    guint i;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(dialog == NULL)
-    {
-        mapman_info.dialog = dialog = gtk_dialog_new_with_buttons(
-                _("Manage Maps"),
-                GTK_WINDOW(_window), GTK_DIALOG_MODAL,
-                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
-                NULL);
-
-        /* Enable the help button. */
-        ossohelp_dialog_help_enable(
-                GTK_DIALOG(mapman_info.dialog), HELP_ID_MAPMAN, _osso);
-
-        /* Clear button. */
-        gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
-                button = gtk_button_new_with_label(_("Clear")));
-        g_signal_connect(G_OBJECT(button), "clicked",
-                          G_CALLBACK(mapman_clear), &mapman_info);
-
-        /* Cancel button. */
-        gtk_dialog_add_button(GTK_DIALOG(dialog),
-                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
-
-        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
-                mapman_info.notebook = gtk_notebook_new(), TRUE, TRUE, 0);
-
-        /* Setup page. */
-        gtk_notebook_append_page(GTK_NOTEBOOK(mapman_info.notebook),
-                vbox = gtk_vbox_new(FALSE, 2),
-                label = gtk_label_new(_("Setup")));
-        gtk_notebook_set_tab_label_packing(
-                GTK_NOTEBOOK(mapman_info.notebook), vbox,
-                FALSE, FALSE, GTK_PACK_START);
-
-        gtk_box_pack_start(GTK_BOX(vbox),
-                hbox = gtk_hbox_new(FALSE, 4),
-                FALSE, FALSE, 0);
-        gtk_box_pack_start(GTK_BOX(hbox),
-                mapman_info.rad_download = gtk_radio_button_new_with_label(
-                    NULL,_("Download Maps")),
-                FALSE, FALSE, 0);
-        gtk_box_pack_start(GTK_BOX(hbox),
-                label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
-                FALSE, FALSE, 0);
-        gtk_container_add(GTK_CONTAINER(label),
-                mapman_info.chk_overwrite
-                        = gtk_check_button_new_with_label(_("Overwrite"))),
-
-        gtk_box_pack_start(GTK_BOX(vbox),
-                mapman_info.rad_delete
-                        = gtk_radio_button_new_with_label_from_widget(
-                            GTK_RADIO_BUTTON(mapman_info.rad_download),
-                            _("Delete Maps")),
-                FALSE, FALSE, 0);
-
-        gtk_box_pack_start(GTK_BOX(vbox),
-                gtk_hseparator_new(),
-                FALSE, FALSE, 0);
-
-        gtk_box_pack_start(GTK_BOX(vbox),
-                mapman_info.rad_by_area
-                        = gtk_radio_button_new_with_label(NULL,
-                            _("By Area (see tab)")),
-                FALSE, FALSE, 0);
-        gtk_box_pack_start(GTK_BOX(vbox),
-                hbox = gtk_hbox_new(FALSE, 4),
-                FALSE, FALSE, 0);
-        gtk_box_pack_start(GTK_BOX(hbox),
-                mapman_info.rad_by_route
-                        = gtk_radio_button_new_with_label_from_widget(
-                            GTK_RADIO_BUTTON(mapman_info.rad_by_area),
-                            _("Along Route - Radius (tiles):")),
-                FALSE, FALSE, 0);
-        gtk_widget_set_sensitive(mapman_info.rad_by_route,
-                _route.head != _route.tail);
-        gtk_box_pack_start(GTK_BOX(hbox),
-                mapman_info.num_route_radius = hildon_number_editor_new(0,100),
-                FALSE, FALSE, 0);
-        hildon_number_editor_set_value(
-                HILDON_NUMBER_EDITOR(mapman_info.num_route_radius),
-                _route_dl_radius);
-
-
-        /* Zoom page. */
-        gtk_notebook_append_page(GTK_NOTEBOOK(mapman_info.notebook),
-                table = gtk_table_new(5, 5, FALSE),
-                label = gtk_label_new(_("Zoom")));
-        gtk_notebook_set_tab_label_packing(
-                GTK_NOTEBOOK(mapman_info.notebook), table,
-                FALSE, FALSE, GTK_PACK_START);
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(
-                    _("Zoom Levels to Download: (0 = most detail)")),
-                0, 4, 0, 1, GTK_FILL, 0, 4, 0);
-        gtk_misc_set_alignment(GTK_MISC(label), 0.f, 0.5f);
-        for(i = 0; i < MAX_ZOOM; i++)
-        {
-            snprintf(buffer, sizeof(buffer), "%d", i);
-            gtk_table_attach(GTK_TABLE(table),
-                    mapman_info.chk_zoom_levels[i]
-                            = gtk_check_button_new_with_label(buffer),
-                    i % 4, i % 4 + 1, i / 4 + 1, i / 4 + 2,
-                    GTK_EXPAND | GTK_FILL, 0, 4, 0);
-        }
-
-        /* Area page. */
-        gtk_notebook_append_page(GTK_NOTEBOOK(mapman_info.notebook),
-            mapman_info.tbl_area = gtk_table_new(3, 4, FALSE),
-            label = gtk_label_new(_("Area")));
-
-        /* Label Columns. */
-        gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
-                label = gtk_label_new(_("Latitude")),
-                1, 2, 0, 1, GTK_FILL, 0, 4, 0);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
-                label = gtk_label_new(_("Longitude")),
-                2, 3, 0, 1, GTK_FILL, 0, 4, 0);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-
-        /* GPS. */
-        gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
-                label = gtk_label_new(_("GPS Location")),
-                0, 1, 1, 2, GTK_FILL, 0, 4, 0);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
-                lbl_gps_lat = gtk_label_new(""),
-                1, 2, 1, 2, GTK_FILL, 0, 4, 0);
-        gtk_label_set_selectable(GTK_LABEL(lbl_gps_lat), TRUE);
-        gtk_misc_set_alignment(GTK_MISC(lbl_gps_lat), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
-                lbl_gps_lon = gtk_label_new(""),
-                2, 3, 1, 2, GTK_FILL, 0, 4, 0);
-        gtk_label_set_selectable(GTK_LABEL(lbl_gps_lon), TRUE);
-        gtk_misc_set_alignment(GTK_MISC(lbl_gps_lon), 1.f, 0.5f);
-
-        /* Center. */
-        gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
-                label = gtk_label_new(_("View Center")),
-                0, 1, 2, 3, GTK_FILL, 0, 4, 0);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
-                lbl_center_lat = gtk_label_new(""),
-                1, 2, 2, 3, GTK_FILL, 0, 4, 0);
-        gtk_label_set_selectable(GTK_LABEL(lbl_center_lat), TRUE);
-        gtk_misc_set_alignment(GTK_MISC(lbl_center_lat), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
-                lbl_center_lon = gtk_label_new(""),
-                2, 3, 2, 3, GTK_FILL, 0, 4, 0);
-        gtk_label_set_selectable(GTK_LABEL(lbl_center_lon), TRUE);
-        gtk_misc_set_alignment(GTK_MISC(lbl_center_lon), 1.f, 0.5f);
-
-        /* default values for Top Left and Bottom Right are defined by the
-         * rectangle of the current and the previous Center */
-
-        /* Top Left. */
-        gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
-                label = gtk_label_new(_("Top-Left")),
-                0, 1, 3, 4, GTK_FILL, 0, 4, 0);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
-                mapman_info.txt_topleft_lat = gtk_entry_new(),
-                1, 2, 3, 4, GTK_EXPAND | GTK_FILL, 0, 4, 0);
-        gtk_entry_set_width_chars(GTK_ENTRY(mapman_info.txt_topleft_lat), 16);
-        gtk_entry_set_alignment(GTK_ENTRY(mapman_info.txt_topleft_lat), 1.f);
-        g_object_set(G_OBJECT(mapman_info.txt_topleft_lat),
-                HILDON_INPUT_MODE_HINT,
-                HILDON_INPUT_MODE_HINT_ALPHANUMERICSPECIAL, NULL);
-        gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
-                mapman_info.txt_topleft_lon = gtk_entry_new(),
-                2, 3, 3, 4, GTK_EXPAND | GTK_FILL, 0, 4, 0);
-        gtk_entry_set_width_chars(GTK_ENTRY(mapman_info.txt_topleft_lon), 16);
-        gtk_entry_set_alignment(GTK_ENTRY(mapman_info.txt_topleft_lon), 1.f);
-        g_object_set(G_OBJECT(mapman_info.txt_topleft_lon),
-                HILDON_INPUT_MODE_HINT,
-                HILDON_INPUT_MODE_HINT_ALPHANUMERICSPECIAL, NULL);
-
-        /* Bottom Right. */
-        gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
-                label = gtk_label_new(_("Bottom-Right")),
-                0, 1, 4, 5, GTK_FILL, 0, 4, 0);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-        gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
-                mapman_info.txt_botright_lat = gtk_entry_new(),
-                1, 2, 4, 5, GTK_EXPAND | GTK_FILL, 0, 4, 0);
-        gtk_entry_set_width_chars(GTK_ENTRY(mapman_info.txt_botright_lat), 16);
-        gtk_entry_set_alignment(GTK_ENTRY(mapman_info.txt_botright_lat), 1.f);
-        g_object_set(G_OBJECT(mapman_info.txt_botright_lat),
-                HILDON_INPUT_MODE_HINT,
-                HILDON_INPUT_MODE_HINT_ALPHANUMERICSPECIAL, NULL);
-        gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
-                mapman_info.txt_botright_lon = gtk_entry_new(),
-                2, 3, 4, 5, GTK_EXPAND | GTK_FILL, 0, 4, 0);
-        gtk_entry_set_width_chars(GTK_ENTRY(mapman_info.txt_botright_lat), 16);
-        gtk_entry_set_alignment(GTK_ENTRY(mapman_info.txt_botright_lon), 1.f);
-        g_object_set(G_OBJECT(mapman_info.txt_botright_lon),
-                HILDON_INPUT_MODE_HINT,
-                HILDON_INPUT_MODE_HINT_ALPHANUMERICSPECIAL, NULL);
-
-        /* Default action is to download by area. */
-        gtk_toggle_button_set_active(
-                GTK_TOGGLE_BUTTON(mapman_info.rad_by_area), TRUE);
-
-        g_signal_connect(G_OBJECT(mapman_info.rad_download), "clicked",
-                          G_CALLBACK(mapman_update_state), &mapman_info);
-        g_signal_connect(G_OBJECT(mapman_info.rad_delete), "clicked",
-                          G_CALLBACK(mapman_update_state), &mapman_info);
-        g_signal_connect(G_OBJECT(mapman_info.rad_by_area), "clicked",
-                          G_CALLBACK(mapman_update_state), &mapman_info);
-        g_signal_connect(G_OBJECT(mapman_info.rad_by_route), "clicked",
-                          G_CALLBACK(mapman_update_state), &mapman_info);
-    }
-
-    /* Initialize fields.  Do no use g_ascii_formatd; these strings will be
-     * output (and parsed) as locale-dependent. */
-
-    lat_format(_gps.lat, buffer);
-    gtk_label_set_text(GTK_LABEL(lbl_gps_lat), buffer);
-    lon_format(_gps.lon, buffer);
-    gtk_label_set_text(GTK_LABEL(lbl_gps_lon), buffer);
-
-    unit2latlon(_center.unitx, _center.unity, lat, lon);
-    lat_format(lat, buffer);
-    gtk_label_set_text(GTK_LABEL(lbl_center_lat), buffer);
-    lon_format(lon, buffer);
-    gtk_label_set_text(GTK_LABEL(lbl_center_lon), buffer);
-
-    /* Initialize to the bounds of the screen. */
-    unit2latlon(x2unit(0), y2unit(0), lat, lon);
-    lat_format(lat, buffer);
-    gtk_entry_set_text(GTK_ENTRY(mapman_info.txt_topleft_lat), buffer);
-    lon_format(lon, buffer);
-    gtk_entry_set_text(GTK_ENTRY(mapman_info.txt_topleft_lon), buffer);
-
-    unit2latlon(x2unit(_screen_width_pixels), y2unit(_screen_height_pixels),
-            lat, lon);
-    lat_format(lat, buffer);
-    gtk_entry_set_text(GTK_ENTRY(mapman_info.txt_botright_lat), buffer);
-    lon_format(lon, buffer);
-    gtk_entry_set_text(GTK_ENTRY(mapman_info.txt_botright_lon), buffer);
-
-    gtk_toggle_button_set_active(
-            GTK_TOGGLE_BUTTON(mapman_info.chk_zoom_levels[_zoom]), TRUE);
-
-    gtk_widget_show_all(dialog);
-
-    mapman_update_state(NULL, &mapman_info);
-
-    if(_curr_repo->type != REPOTYPE_NONE)
-    {
-        gtk_widget_set_sensitive(mapman_info.rad_download, TRUE);
-    }
-    else
-    {
-        gtk_widget_set_sensitive(mapman_info.rad_download, FALSE);
-        popup_error(dialog,
-                _("NOTE: You must set a Map URI in the current repository in "
-                    "order to download maps."));
-    }
-
-    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
-    {
-        gboolean is_deleting = gtk_toggle_button_get_active(
-                GTK_TOGGLE_BUTTON(mapman_info.rad_delete));
-        gboolean is_overwriting = gtk_toggle_button_get_active(
-                GTK_TOGGLE_BUTTON(mapman_info.chk_overwrite));
-        if(gtk_toggle_button_get_active(
-                    GTK_TOGGLE_BUTTON(mapman_info.rad_by_route)))
-        {
-            if(mapman_by_route(&mapman_info, is_deleting, is_overwriting))
-                break;
-        }
-        else
-        {
-            const gchar *text;
-            gchar *error_check;
-            gdouble start_lat, start_lon, end_lat, end_lon;
-
-            text = gtk_entry_get_text(GTK_ENTRY(mapman_info.txt_topleft_lat));
-            start_lat = strdmstod(text, &error_check);
-            if(text == error_check || start_lat < -90. || start_lat > 90.) {
-                popup_error(dialog, _("Invalid Top-Left Latitude"));
-                continue;
-            }
-
-            text = gtk_entry_get_text(GTK_ENTRY(mapman_info.txt_topleft_lon));
-            start_lon = strdmstod(text, &error_check);
-            if(text == error_check || start_lon < -180. || start_lon>180.) {
-                popup_error(dialog, _("Invalid Top-Left Longitude"));
-                continue;
-            }
-
-            text = gtk_entry_get_text(GTK_ENTRY(mapman_info.txt_botright_lat));
-            end_lat = strdmstod(text, &error_check);
-            if(text == error_check || end_lat < -90. || end_lat > 90.) {
-                popup_error(dialog, _("Invalid Bottom-Right Latitude"));
-                continue;
-            }
-
-            text = gtk_entry_get_text(GTK_ENTRY(mapman_info.txt_botright_lon));
-            end_lon = strdmstod(text, &error_check);
-            if(text == error_check || end_lon < -180. || end_lon > 180.) {
-                popup_error(dialog,_("Invalid Bottom-Right Longitude"));
-                continue;
-            }
-
-            if(mapman_by_area(start_lat, start_lon, end_lat, end_lon,
-                        &mapman_info, is_deleting, is_overwriting))
-                break;
-        }
-    }
-
-    gtk_widget_hide(dialog);
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_zoomin(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(_zoom > 0)
-    {
-        gchar buffer[80];
-        snprintf(buffer, sizeof(buffer),"%s %d",
-                _("Zoom to Level"), _zoom - 1);
-        MACRO_BANNER_SHOW_INFO(_window, buffer);
-        map_set_zoom(_zoom - 1);
-    }
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_zoomout(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(_zoom < MAX_ZOOM - 1)
-    {
-        gchar buffer[80];
-        snprintf(buffer, sizeof(buffer),"%s %d",
-                _("Zoom to Level"), _zoom + 1);
-        MACRO_BANNER_SHOW_INFO(_window, buffer);
-        map_set_zoom(_zoom + 1);
-    }
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_fullscreen(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if((_fullscreen = gtk_check_menu_item_get_active(
-                GTK_CHECK_MENU_ITEM(_menu_fullscreen_item))))
-        gtk_window_fullscreen(GTK_WINDOW(_window));
-    else
-        gtk_window_unfullscreen(GTK_WINDOW(_window));
-
-    gtk_idle_add((GSourceFunc)window_present, NULL);
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_enable_gps(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if((_enable_gps = gtk_check_menu_item_get_active(
-                GTK_CHECK_MENU_ITEM(_menu_enable_gps_item))))
-    {
-        if(_rcvr_mac)
-        {
-            set_conn_state(RCVR_DOWN);
-            rcvr_connect_now();
-        }
-        else
-        {
-            popup_error(_window,
-                    _("Cannot enable GPS until a GPS Receiver MAC "
-                    "is set in the Settings dialog box."));
-            gtk_check_menu_item_set_active(
-                    GTK_CHECK_MENU_ITEM(_menu_enable_gps_item), FALSE);
-        }
-    }
-    else
-    {
-        if(_conn_state > RCVR_OFF)
-            set_conn_state(RCVR_OFF);
-        rcvr_disconnect();
-        track_add(0, FALSE);
-        _speed_excess = FALSE;
-    }
-    map_move_mark();
-    gps_show_info();
-    gtk_widget_set_sensitive(GTK_WIDGET(_menu_gps_details_item), _enable_gps);
-    gtk_widget_set_sensitive(GTK_WIDGET(_menu_gps_reset_item), _enable_gps);
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_auto_download(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if((_auto_download = gtk_check_menu_item_get_active(
-            GTK_CHECK_MENU_ITEM(_menu_auto_download_item))))
-    {
-        if(_curr_repo->url == REPOTYPE_NONE)
-            popup_error(_window,
-                _("NOTE: You must set a Map URI in the current repository in "
-                    "order to download maps."));
-        map_force_redraw();
-    }
-
-    if (!_auto_download && _download_banner) {
-      gtk_widget_destroy(_download_banner);
-      _download_banner = 0;
-
-      _iap_connecting = FALSE;
-      _iap_connected = FALSE;
-      _num_downloads = _curr_download = 0;
-
-      /* clean up curl */
-      CURL *curr;
-      while((curr = g_queue_pop_tail(_curl_easy_queue)))
-          curl_easy_cleanup(curr);
-
-      curl_multi_cleanup(_curl_multi);
-      _curl_multi = NULL;
-      _curl_sid = 0;
-    }
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_gps_reset(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    reset_bluetooth();
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_gps_details(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    gps_details();
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_settings(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(settings_dialog())
-    {
-        /* Settings have changed - reconnect to receiver. */
-        if(_enable_gps)
-        {
-            set_conn_state(RCVR_DOWN);
-            rcvr_disconnect();
-            rcvr_connect_now();
-        }
-    }
-    MACRO_RECALC_FOCUS_BASE();
-    MACRO_RECALC_FOCUS_SIZE();
-    map_force_redraw();
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_help(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    ossohelp_show(_osso, HELP_ID_INTRO, 0);
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_about(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    ossohelp_show(_osso, HELP_ID_ABOUT, OSSO_HELP_SHOW_DIALOG);
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-category_delete(GtkWidget *widget, DeletePOI *dpoi)
-{
-    GtkWidget *confirm;
-    guint i;
-    gchar *buffer;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    buffer = g_strdup_printf("%s\n\t%s\n%s",
-            _("Delete category?"),
-            dpoi->txt_label,
-            _("WARNING: All POIs in that category will also be deleted!"));
-    confirm = hildon_note_new_confirmation (GTK_WINDOW(_window), buffer);
-    g_free(buffer);
-    i = gtk_dialog_run (GTK_DIALOG (confirm));
-    gtk_widget_destroy (GTK_WIDGET (confirm));
-
-    if(i == GTK_RESPONSE_OK)
-    {
-        /* delete dpoi->poi_id */
-        if(SQLITE_OK != sqlite3_bind_int(_stmt_delete_poi_by_catid, 1,
-                    dpoi->id) ||
-           SQLITE_DONE != sqlite3_step(_stmt_delete_poi_by_catid))
-        {
-            MACRO_BANNER_SHOW_INFO(_window, _("Problem deleting POI"));
-            sqlite3_reset(_stmt_delete_poi_by_catid);
-            return FALSE;
-        }
-        sqlite3_reset(_stmt_delete_poi_by_catid);
-
-        if(SQLITE_OK != sqlite3_bind_int(_stmt_delete_cat, 1, dpoi->id) ||
-           SQLITE_DONE != sqlite3_step(_stmt_delete_cat))
-        {
-            MACRO_BANNER_SHOW_INFO(_window, _("Problem deleting category"));
-            sqlite3_reset(_stmt_delete_cat);
-            return FALSE;
-        }
-        sqlite3_reset(_stmt_delete_cat);
-
-        gtk_widget_hide_all(dpoi->dialog);
-        map_force_redraw();
-    }
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-category_dialog(guint cat_id)
-{
-    gchar *cat_label = NULL, *cat_desc = NULL;
-    guint cat_enabled;
-    GtkWidget *dialog;
-    GtkWidget *table;
-    GtkWidget *label;
-    GtkWidget *txt_label;
-    GtkWidget *txt_desc;
-    GtkWidget *btn_delete = NULL;
-    GtkWidget *txt_scroll;
-    GtkWidget *chk_enabled;
-    GtkTextBuffer *desc_txt;
-    GtkTextIter begin, end;
-    gboolean results = TRUE;
-    DeletePOI dpoi = {NULL, NULL, 0};
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(cat_id > 0)
-    {
-        if(SQLITE_OK != sqlite3_bind_double(_stmt_select_cat, 1, cat_id) ||
-           SQLITE_ROW != sqlite3_step(_stmt_select_cat))
-        {
-            vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
-            sqlite3_reset(_stmt_select_cat);
-            return FALSE;
-        }
-
-        cat_label = g_strdup(sqlite3_column_text(_stmt_select_cat, 0));
-        cat_desc = g_strdup(sqlite3_column_text(_stmt_select_cat, 1));
-        cat_enabled = sqlite3_column_int(_stmt_select_cat, 2);
-
-        sqlite3_reset(_stmt_select_cat);
-
-        dialog = gtk_dialog_new_with_buttons(_("Edit Category"),
-            GTK_WINDOW(_window), GTK_DIALOG_MODAL,
-            GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
-            NULL);
-
-        gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
-                btn_delete = gtk_button_new_with_label(_("Delete")));
-
-        dpoi.dialog = dialog;
-        dpoi.txt_label = g_strdup(cat_label);
-        dpoi.id = cat_id;
-
-        g_signal_connect(G_OBJECT(btn_delete), "clicked",
-                          G_CALLBACK(category_delete), &dpoi);
-
-        gtk_dialog_add_button(GTK_DIALOG(dialog),
-                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
-    }
-    else
-    {
-        cat_enabled = 1;
-        cat_label = g_strdup("");
-        cat_id = 0;
-        cat_desc = g_strdup("");
-
-        dialog = gtk_dialog_new_with_buttons(_("Add Category"),
-            GTK_WINDOW(_window), GTK_DIALOG_MODAL,
-            GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
-            GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
-            NULL);
-    }
-
-    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
-            table = gtk_table_new(6, 4, FALSE), TRUE, TRUE, 0);
-
-    gtk_table_attach(GTK_TABLE(table),
-            label = gtk_label_new(_("Label")),
-            0, 1, 0, 1, GTK_FILL, 0, 2, 4);
-    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-    gtk_table_attach(GTK_TABLE(table),
-            txt_label = gtk_entry_new(),
-            1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-
-    gtk_table_attach(GTK_TABLE(table),
-            label = gtk_label_new(_("Description")),
-            0, 1, 1, 2, GTK_FILL, 0, 2, 4);
-    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-
-    txt_scroll = gtk_scrolled_window_new(NULL, NULL);
-    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(txt_scroll),
-                                   GTK_SHADOW_IN);
-    gtk_table_attach(GTK_TABLE(table),
-            txt_scroll,
-            1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-
-    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(txt_scroll),
-                                 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-
-    txt_desc = gtk_text_view_new ();
-    gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt_desc), GTK_WRAP_WORD);
-
-    gtk_container_add(GTK_CONTAINER(txt_scroll), txt_desc);
-    gtk_widget_set_size_request(GTK_WIDGET(txt_scroll), 400, 60);
-
-    desc_txt = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txt_desc));
-
-    gtk_table_attach(GTK_TABLE(table),
-            chk_enabled = gtk_check_button_new_with_label(
-                _("Enabled")),
-            0, 2, 2, 3, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-
-    /* label */
-    gtk_entry_set_text(GTK_ENTRY(txt_label), cat_label);
-
-    /* desc */
-    gtk_text_buffer_set_text(desc_txt, cat_desc, -1);
-
-    /* enabled */
-    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chk_enabled),
-            (cat_enabled == 1 ? TRUE : FALSE));
-
-    g_free(cat_label);
-    cat_label = NULL;
-    g_free(cat_desc);
-    cat_desc = NULL;
-
-    gtk_widget_show_all(dialog);
-
-    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
-    {
-        if(strlen(gtk_entry_get_text(GTK_ENTRY(txt_label))))
-            cat_label = g_strdup(gtk_entry_get_text(GTK_ENTRY(txt_label)));
-        else
-        {
-            popup_error(dialog, _("Please specify a name for the category."));
-            continue;
-        }
-
-        gtk_text_buffer_get_iter_at_offset(desc_txt, &begin,0 );
-        gtk_text_buffer_get_end_iter (desc_txt, &end);
-        cat_desc = gtk_text_buffer_get_text(desc_txt, &begin, &end, TRUE);
-
-        cat_enabled = (gtk_toggle_button_get_active(
-                GTK_TOGGLE_BUTTON(chk_enabled)) ? 1 : 0);
-
-        if(cat_id > 0)
-        {
-            /* edit category */
-            if(SQLITE_OK != sqlite3_bind_text(_stmt_update_cat, 1, cat_label,
-                        -1, g_free) ||
-               SQLITE_OK != sqlite3_bind_text(_stmt_update_cat, 2, cat_desc,
-                        -1, g_free) ||
-               SQLITE_OK != sqlite3_bind_int(_stmt_update_cat, 3,cat_enabled)||
-               SQLITE_OK != sqlite3_bind_int(_stmt_update_cat, 4, cat_id) ||
-               SQLITE_DONE != sqlite3_step(_stmt_update_cat))
-            {
-                MACRO_BANNER_SHOW_INFO(_window,_("Problem updating category"));
-                results = FALSE;
-            }
-            sqlite3_reset(_stmt_update_cat);
-        }
-        else
-        {
-            /* add category */
-            if(SQLITE_OK != sqlite3_bind_text(_stmt_insert_cat, 1, cat_label,
-                        -1, g_free) ||
-               SQLITE_OK != sqlite3_bind_text(_stmt_insert_cat, 2, cat_desc,
-                        -1, g_free) ||
-               SQLITE_OK != sqlite3_bind_int(_stmt_insert_cat, 3,cat_enabled)||
-               SQLITE_DONE != sqlite3_step(_stmt_insert_cat))
-            {
-                MACRO_BANNER_SHOW_INFO(_window, _("Problem adding category"));
-                results = FALSE;
-            }
-            sqlite3_reset(_stmt_insert_cat);
-        }
-        break;
-    }
-
-    g_free(dpoi.txt_label);
-
-    g_object_unref (desc_txt);
-
-    gtk_widget_hide_all(dialog);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-    return results;
-}
-
-static void
-category_toggled(GtkCellRendererToggle *cell, gchar *path, GtkListStore **data)
-{
-    GtkTreeIter iter;
-    gboolean cat_enabled;
-    guint cat_id;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    GtkTreeModel *model = GTK_TREE_MODEL(*data);
-    if( !gtk_tree_model_get_iter_from_string(model, &iter, path) )
-        return;
-
-    gtk_tree_model_get(model, &iter, CAT_ENABLED, &cat_enabled, -1);
-    gtk_tree_model_get(model, &iter, CAT_ID, &cat_id, -1);
-
-    cat_enabled ^= 1;
-
-    if(SQLITE_OK != sqlite3_bind_int(_stmt_toggle_cat, 1, cat_enabled) ||
-       SQLITE_OK != sqlite3_bind_int(_stmt_toggle_cat, 2, cat_id) ||
-       SQLITE_DONE != sqlite3_step(_stmt_toggle_cat))
-    {
-        MACRO_BANNER_SHOW_INFO(_window, _("Problem updating Category"));
-    }
-    else
-        gtk_list_store_set(GTK_LIST_STORE(model), &iter,
-                   CAT_ENABLED, cat_enabled, -1);
-
-    sqlite3_reset(_stmt_toggle_cat);
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-}
-
-static GtkListStore*
-generate_store()
-{
-    GtkTreeIter iter;
-    GtkListStore *store;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    store = gtk_list_store_new(CAT_NUM_COLUMNS,
-                               G_TYPE_UINT,
-                               G_TYPE_BOOLEAN,
-                               G_TYPE_STRING,
-                               G_TYPE_STRING,
-                               G_TYPE_UINT);
-
-    while(SQLITE_ROW == sqlite3_step(_stmt_selall_cat))
-    {
-        gtk_list_store_append(store, &iter);
-        gtk_list_store_set(store, &iter,
-                CAT_ID, sqlite3_column_int(_stmt_selall_cat, 0),
-                CAT_ENABLED, sqlite3_column_int(_stmt_selall_cat, 3),
-                CAT_LABEL, sqlite3_column_text(_stmt_selall_cat, 1),
-                CAT_DESC, sqlite3_column_text(_stmt_selall_cat, 2),
-                CAT_POI_CNT, sqlite3_column_int(_stmt_selall_cat, 4),
-                -1);
-    }
-    sqlite3_reset(_stmt_selall_cat);
-
-    vprintf("%s(): return %p\n", __PRETTY_FUNCTION__, store);
-    return store;
-}
-
-static gboolean
-category_add(GtkWidget *widget, GtkWidget *tree_view)
-{
-    GtkListStore *store;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(category_dialog(0))
-    {
-        store = generate_store();
-        gtk_tree_view_set_model(
-                GTK_TREE_VIEW(tree_view),
-                GTK_TREE_MODEL(store));
-        g_object_unref(G_OBJECT(store));
-    }
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-category_edit(GtkWidget *widget, GtkWidget *tree_view)
-{
-    GtkTreeIter iter;
-    GtkTreeModel *store;
-    GtkTreeSelection *selection;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    store = gtk_tree_view_get_model(GTK_TREE_VIEW(tree_view));
-    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view));
-    if(gtk_tree_selection_get_selected(selection, &store, &iter))
-    {
-        GValue val;
-        memset(&val, 0, sizeof(val));
-        gtk_tree_model_get_value(store, &iter, 0, &val);
-        if(category_dialog(g_value_get_uint(&val)))
-        {
-            GtkListStore *new_store = generate_store();
-            gtk_tree_view_set_model(
-                    GTK_TREE_VIEW(tree_view),
-                    GTK_TREE_MODEL(new_store));
-            g_object_unref(G_OBJECT(new_store));
-        }
-    }
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-category_list()
-{
-    static GtkWidget *dialog = NULL;
-    static GtkWidget *tree_view = NULL;
-    static GtkWidget *sw = NULL;
-    static GtkWidget *btn_edit = NULL;
-    static GtkWidget *btn_add = NULL;
-    static GtkTreeViewColumn *column = NULL;
-    static GtkCellRenderer *renderer = NULL;
-    static GtkListStore *store;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    store = generate_store();
-
-    if(!store)
-        return TRUE;
-
-    if(dialog == NULL)
-    {
-        dialog = gtk_dialog_new_with_buttons(_("POI Categories"),
-                GTK_WINDOW(_window), GTK_DIALOG_MODAL,
-                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
-                NULL);
-
-        /* Enable the help button. */
-        ossohelp_dialog_help_enable(
-                GTK_DIALOG(dialog), HELP_ID_POICAT, _osso);
-
-        gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
-                btn_edit = gtk_button_new_with_label(_("Edit")));
-
-        gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
-                btn_add = gtk_button_new_with_label(_("Add")));
-
-        sw = gtk_scrolled_window_new(NULL, NULL);
-        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (sw),
-                      GTK_POLICY_NEVER,
-                      GTK_POLICY_AUTOMATIC);
-        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
-                sw, TRUE, TRUE, 0);
-
-        tree_view = gtk_tree_view_new();
-        /* Maemo-related? */
-        g_object_set(tree_view, "allow-checkbox-mode", FALSE, NULL);
-        gtk_container_add (GTK_CONTAINER (sw), tree_view);
-
-        gtk_tree_selection_set_mode(
-                gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view)),
-                GTK_SELECTION_SINGLE);
-        gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree_view), TRUE);
-
-        renderer = gtk_cell_renderer_text_new();
-        column = gtk_tree_view_column_new_with_attributes(
-                _("ID"), renderer, "text", CAT_ID, NULL);
-        gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
-        gtk_tree_view_column_set_max_width (column, 1);
-
-        renderer = gtk_cell_renderer_toggle_new();
-        g_signal_connect (renderer, "toggled",
-                G_CALLBACK (category_toggled), &store);
-        column = gtk_tree_view_column_new_with_attributes(
-                _("Enabled"), renderer, "active", CAT_ENABLED, NULL);
-        gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
-
-        renderer = gtk_cell_renderer_text_new();
-        column = gtk_tree_view_column_new_with_attributes(
-                _("Label"), renderer, "text", CAT_LABEL, NULL);
-        gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
-
-        renderer = gtk_cell_renderer_text_new();
-        column = gtk_tree_view_column_new_with_attributes(
-                _("Description"), renderer, "text", CAT_DESC, NULL);
-        gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
-
-        renderer = gtk_cell_renderer_text_new();
-        column = gtk_tree_view_column_new_with_attributes(
-                _("# POIs"), renderer, "text", CAT_POI_CNT, NULL);
-        gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
-
-        gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 300);
-
-        g_signal_connect(G_OBJECT(btn_edit), "clicked",
-                G_CALLBACK(category_edit), tree_view);
-
-        g_signal_connect(G_OBJECT(btn_add), "clicked",
-                G_CALLBACK(category_add), tree_view);
-    }
-
-    gtk_tree_view_set_model(GTK_TREE_VIEW(tree_view), GTK_TREE_MODEL(store));
-    g_object_unref(G_OBJECT(store));
-
-    gtk_widget_show_all(dialog);
-
-    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
-    {
-        break;
-    }
-
-    gtk_widget_hide(dialog);
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-menu_cb_category(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(category_list())
-        map_force_redraw();
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-poi_delete(GtkWidget *widget, DeletePOI *dpoi)
-{
-    GtkWidget *confirm;
-    guint i;
-    gchar *buffer;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    buffer = g_strdup_printf("%s\n%s", _("Delete POI?"), dpoi->txt_label);
-    confirm = hildon_note_new_confirmation (GTK_WINDOW(_window), buffer);
-    g_free(buffer);
-    i = gtk_dialog_run (GTK_DIALOG (confirm));
-    gtk_widget_destroy (GTK_WIDGET (confirm));
-
-    if(i == GTK_RESPONSE_OK)
-    {
-        if(SQLITE_OK != sqlite3_bind_int(_stmt_delete_poi, 1, dpoi->id) ||
-           SQLITE_DONE != sqlite3_step(_stmt_delete_poi))
-        {
-            MACRO_BANNER_SHOW_INFO(_window, _("Problem deleting POI"));
-        }
-        else
-        {
-            gtk_widget_hide_all(dpoi->dialog);
-            map_force_redraw();
-        }
-        sqlite3_reset(_stmt_delete_poi);
-    }
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static void
-poi_populate_cat_combo(GtkWidget *cmb_category, guint cat_id)
-{
-    GtkTreeIter active;
-    GtkListStore *store;
-    gboolean has_active = FALSE;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    store = GTK_LIST_STORE(gtk_combo_box_get_model(
-                GTK_COMBO_BOX(cmb_category)));
-    gtk_list_store_clear(store);
-
-    while(SQLITE_ROW == sqlite3_step(_stmt_selall_cat))
-    {
-        GtkTreeIter iter;
-        guint cid = sqlite3_column_int(_stmt_selall_cat, 0);
-        gtk_list_store_append(store, &iter);
-        gtk_list_store_set(store, &iter,
-                0, cid,
-                1, sqlite3_column_text(_stmt_selall_cat, 1),
-                -1);
-        if(cid == cat_id)
-        {
-            active = iter;
-            has_active = TRUE;
-        }
-    }
-    sqlite3_reset(_stmt_selall_cat);
-
-    if(!has_active)
-        gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &active);
-
-    gtk_combo_box_set_active_iter(GTK_COMBO_BOX(cmb_category), &active);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-typedef struct _PoiCategoryEditInfo PoiCategoryEditInfo;
-struct _PoiCategoryEditInfo
-{
-    GtkWidget *cmb_category;
-    guint cat_id;
-};
-
-static gboolean
-poi_edit_cat(GtkWidget *widget, PoiCategoryEditInfo *data)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-    if(category_list())
-        poi_populate_cat_combo(data->cmb_category, data->cat_id);
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-poi_dialog(POIAction action, guint unitx, guint unity)
-{
-    PoiInfo poi;
-    gchar slat1[10], slon1[10];
-    gchar buffer[16];
-    GtkWidget *dialog;
-    GtkWidget *table;
-    GtkWidget *label;
-    GtkWidget *txt_label;
-    GtkWidget *txt_lat;
-    GtkWidget *txt_lon;
-    GtkWidget *cmb_category;
-    GtkWidget *txt_desc;
-    GtkWidget *btn_delete = NULL;
-    GtkWidget *btn_catedit;
-    GtkWidget *hbox;
-    GtkWidget *txt_scroll;
-    GtkTextBuffer *desc_txt;
-    GtkTextIter begin, end;
-    DeletePOI dpoi = {NULL, NULL, 0};
-    PoiCategoryEditInfo pcedit;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(action == ACTION_EDIT_POI)
-    {
-        if(!select_poi(unitx, unity, &poi, FALSE)) /* FALSE = not quick */
-        {
-            return FALSE;
-        }
-
-        dialog = gtk_dialog_new_with_buttons(_("Edit POI"),
-            GTK_WINDOW(_window), GTK_DIALOG_MODAL,
-            GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
-            NULL);
-
-        gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
-                btn_delete = gtk_button_new_with_label(_("Delete")));
-
-        dpoi.dialog = dialog;
-        dpoi.txt_label = g_strdup(poi.label);
-        dpoi.id = poi.poi_id;
-
-        g_signal_connect(G_OBJECT(btn_delete), "clicked",
-                          G_CALLBACK(poi_delete), &dpoi);
-
-        gtk_dialog_add_button(GTK_DIALOG(dialog),
-                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
-    }
-    else
-    {
-        if(SQLITE_ROW == sqlite3_step(_stmt_nextlabel_poi))
-            poi.label = g_strdup_printf("Point%06d",
-                    sqlite3_column_int(_stmt_nextlabel_poi, 0));
-        sqlite3_reset(_stmt_nextlabel_poi);
-
-        unit2latlon(unitx, unity, poi.lat, poi.lon);
-
-        poi.poi_id = 0;
-        poi.cat_id = 0;
-        poi.desc = g_strdup("");
-
-        dialog = gtk_dialog_new_with_buttons(_("Add POI"),
-            GTK_WINDOW(_window), GTK_DIALOG_MODAL,
-            GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
-            GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
-            NULL);
-    }
-
-    /* Set the lat/lon strings. */
-    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
-            table = gtk_table_new(6, 4, FALSE), TRUE, TRUE, 0);
-
-    gtk_table_attach(GTK_TABLE(table),
-            label = gtk_label_new(_("Lat")),
-            0, 1, 0, 1, GTK_FILL, 0, 2, 4);
-    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-    gtk_table_attach(GTK_TABLE(table),
-            txt_lat = gtk_entry_new(),
-            1, 2, 0, 1, GTK_FILL, 0, 2, 4);
-
-    gtk_table_attach(GTK_TABLE(table),
-            label = gtk_label_new(_("Lon")),
-            2, 3, 0, 1, GTK_FILL, 0, 2, 4);
-    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-    gtk_table_attach(GTK_TABLE(table),
-            txt_lon = gtk_entry_new(),
-            3, 4, 0, 1, GTK_FILL, 0, 2, 4);
-
-    gtk_table_attach(GTK_TABLE(table),
-            label = gtk_label_new(_("Label")),
-            0, 1, 1, 2, GTK_FILL, 0, 2, 4);
-    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-    gtk_table_attach(GTK_TABLE(table),
-            txt_label = gtk_entry_new(),
-            1, 4, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-
-    gtk_table_attach(GTK_TABLE(table),
-            label = gtk_label_new(_("Category")),
-            0, 1, 3, 4, GTK_FILL, 0, 2, 4);
-    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-    gtk_table_attach(GTK_TABLE(table),
-            hbox = gtk_hbox_new(FALSE, 4),
-            1, 4, 3, 4, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-    gtk_box_pack_start(GTK_BOX(hbox),
-            cmb_category = gtk_combo_box_new_with_model(
-                GTK_TREE_MODEL(gtk_list_store_new(2,
-                        G_TYPE_INT, /* Category ID */
-                        G_TYPE_STRING))), /* Category Label */
-            FALSE, FALSE, 4);
-    /* Set up the view for the combo box. */
-    {
-        GtkCellRenderer *renderer;
-        renderer = gtk_cell_renderer_text_new();
-        gtk_cell_layout_pack_start(
-                GTK_CELL_LAYOUT(cmb_category), renderer, TRUE);
-        gtk_cell_layout_set_attributes(
-                GTK_CELL_LAYOUT(cmb_category), renderer, "text", 1, NULL);
-    }
-
-    gtk_box_pack_start(GTK_BOX(hbox),
-            btn_catedit = gtk_button_new_with_label(_("Edit Categories...")),
-            FALSE, FALSE, 4);
-
-    gtk_table_attach(GTK_TABLE(table),
-            label = gtk_label_new(_("Description")),
-            0, 1, 5, 6, GTK_FILL, 0, 2, 4);
-    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-
-    txt_scroll = gtk_scrolled_window_new(NULL, NULL);
-    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(txt_scroll),
-                                   GTK_SHADOW_IN);
-    gtk_table_attach(GTK_TABLE(table),
-            txt_scroll,
-            1, 4, 5, 6, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-
-    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(txt_scroll),
-                                 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-
-    txt_desc = gtk_text_view_new ();
-    gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt_desc), GTK_WRAP_WORD);
-
-    gtk_container_add(GTK_CONTAINER(txt_scroll), txt_desc);
-    gtk_widget_set_size_request(GTK_WIDGET(txt_scroll), 400, 60);
-
-    desc_txt = gtk_text_view_get_buffer (GTK_TEXT_VIEW (txt_desc));
-
-    /* Lat/Lon */
-    snprintf(buffer, sizeof(buffer), "%.06f", poi.lat);
-    gtk_entry_set_text(GTK_ENTRY(txt_lat), buffer);
-    snprintf(buffer, sizeof(buffer), "%.06f", poi.lon);
-    gtk_entry_set_text(GTK_ENTRY(txt_lon), buffer);
-
-    /* label */
-    gtk_entry_set_text(GTK_ENTRY(txt_label), poi.label);
-
-    /* category */
-    poi_populate_cat_combo(cmb_category, poi.cat_id);
-
-    /* poi_desc */
-    gtk_text_buffer_set_text(desc_txt, poi.desc, -1);
-
-    /* Connect Signals */
-    pcedit.cmb_category = cmb_category;
-    pcedit.cat_id = poi.cat_id;
-    g_signal_connect(G_OBJECT(btn_catedit), "clicked",
-            G_CALLBACK(poi_edit_cat), &pcedit);
-    gtk_widget_show_all(dialog);
-
-    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
-    {
-        const gchar *poi_label = NULL;
-        gchar *poi_desc = NULL;
-        GtkTreeIter iter;
-        const gchar *text;
-        gchar *error_check;
-
-        text = gtk_entry_get_text(GTK_ENTRY(txt_lat));
-        poi.lat = strdmstod(text, &error_check);
-        if(text == error_check || poi.lat < -90. || poi.lat > 90.) {
-            popup_error(dialog, _("Invalid Latitude"));
-            continue;
-        }
-
-        text = gtk_entry_get_text(GTK_ENTRY(txt_lon));
-        poi.lon = strdmstod(text, &error_check);
-        if(text == error_check || poi.lon < -180. || poi.lon > 180.) {
-            popup_error(dialog, _("Invalid Longitude"));
-            continue;
-        }
-
-        if(strlen(gtk_entry_get_text(GTK_ENTRY(txt_label))))
-            poi_label = gtk_entry_get_text(GTK_ENTRY(txt_label));
-        else
-        {
-            popup_error(dialog, _("Please specify a name for the POI."));
-            continue;
-        }
-
-        if(!gtk_combo_box_get_active_iter(
-                GTK_COMBO_BOX(cmb_category), &iter))
-        {
-            popup_error(dialog, _("Please specify a category for the POI."));
-            continue;
-        }
-
-        gtk_text_buffer_get_iter_at_offset(desc_txt, &begin,0 );
-        gtk_text_buffer_get_end_iter (desc_txt, &end);
-        poi_desc = gtk_text_buffer_get_text(desc_txt, &begin, &end, TRUE);
-
-        gtk_tree_model_get(
-                gtk_combo_box_get_model(GTK_COMBO_BOX(cmb_category)),
-                &iter, 0, &poi.cat_id, -1);
-
-        if(action == ACTION_EDIT_POI)
-        {
-            /* edit poi */
-            if(SQLITE_OK != sqlite3_bind_double(
-                        _stmt_update_poi, 1, poi.lat) ||
-               SQLITE_OK != sqlite3_bind_double(
-                   _stmt_update_poi, 2, poi.lon) ||
-               SQLITE_OK != sqlite3_bind_text(_stmt_update_poi, 3, poi_label,
-                        -1, SQLITE_STATIC) ||
-               SQLITE_OK != sqlite3_bind_text(_stmt_update_poi, 4, poi_desc,
-                   -1, g_free) ||
-               SQLITE_OK != sqlite3_bind_int(
-                   _stmt_update_poi, 5, poi.cat_id) ||
-               SQLITE_OK != sqlite3_bind_int(
-                   _stmt_update_poi, 6, poi.poi_id) ||
-               SQLITE_DONE != sqlite3_step(_stmt_update_poi))
-            {
-                MACRO_BANNER_SHOW_INFO(_window, _("Problem updating POI"));
-            }
-            else
-            {
-                map_force_redraw();
-            }
-            sqlite3_reset(_stmt_update_poi);
-        }
-        else
-        {
-            /* add poi */
-            g_ascii_dtostr(slat1, sizeof(slat1), poi.lat);
-            g_ascii_dtostr(slon1, sizeof(slon1), poi.lon);
-            if(SQLITE_OK != sqlite3_bind_double(_stmt_insert_poi, 1, poi.lat)
-            || SQLITE_OK != sqlite3_bind_double(_stmt_insert_poi, 2, poi.lon)
-            || SQLITE_OK != sqlite3_bind_text(_stmt_insert_poi, 3, poi_label,
-                   -1, g_free)
-            || SQLITE_OK != sqlite3_bind_text(_stmt_insert_poi, 4, poi_desc,
-                   -1, g_free)
-            || SQLITE_OK != sqlite3_bind_int(_stmt_insert_poi, 5, poi.cat_id)
-            || SQLITE_DONE != sqlite3_step(_stmt_insert_poi))
-            {
-                MACRO_BANNER_SHOW_INFO(_window, _("Problem adding POI"));
-            }
-            else
-            {
-                MACRO_MAP_RENDER_DATA();
-            }
-            sqlite3_reset(_stmt_insert_poi);
-        }
-        break;
-    }
-
-    g_free(dpoi.txt_label);
-
-    g_free(poi.label);
-    g_free(poi.desc);
-
-    gtk_widget_hide_all(dialog);
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-typedef struct {
-    gdouble glat, glon;
-    GtkWidget *fmt_combo;
-    GtkWidget *lat;
-    GtkWidget *lon;
-} LatlonDialog;
-
-static void
-latlon_cb_copy_clicked(GtkWidget *widget, LatlonDialog *lld) {
-    gchar buffer[42];
-
-    snprintf(buffer, sizeof(buffer),
-            "%s %s",
-            gtk_label_get_text(GTK_LABEL(lld->lat)),
-            gtk_label_get_text(GTK_LABEL(lld->lon)));
-
-    gtk_clipboard_set_text(
-            gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), buffer, -1);
-}
-
-static void
-latlon_cb_fmt_changed(GtkWidget *widget, LatlonDialog *lld) {
-  DegFormat fmt;
-
-  fmt = gtk_combo_box_get_active(GTK_COMBO_BOX(lld->fmt_combo));
-
-  {
-    guint old = _degformat; /* augh... */
-    gchar buffer[LL_FMT_LEN];
-
-    _degformat = fmt;
-    lat_format(lld->glat, buffer);
-    gtk_label_set_label(GTK_LABEL(lld->lat), buffer);
-    lon_format(lld->glon, buffer);
-    gtk_label_set_label(GTK_LABEL(lld->lon), buffer);
-    _degformat = old;
-  }
-}
-
-static gboolean
-latlon_dialog(gdouble lat, gdouble lon)
-{
-    LatlonDialog lld;
-    GtkWidget *dialog;
-    GtkWidget *table;
-    GtkWidget *label;
-    GtkWidget *txt_lat;
-    GtkWidget *txt_lon;
-    GtkWidget *cmb_format;
-    GtkWidget *btn_copy = NULL;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    dialog = gtk_dialog_new_with_buttons(_("Show Position"),
-            GTK_WINDOW(_window), GTK_DIALOG_MODAL,
-            GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
-            NULL);
-
-    /* Set the lat/lon strings. */
-    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
-            table = gtk_table_new(5, 2, FALSE), TRUE, TRUE, 0);
-
-    gtk_table_attach(GTK_TABLE(table),
-            label = gtk_label_new(_("Lat")),
-            0, 1, 0, 1, GTK_FILL, 0, 2, 4);
-    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-    gtk_table_attach(GTK_TABLE(table),
-            txt_lat = gtk_label_new(""),
-            1, 2, 0, 1, GTK_FILL, 0, 2, 4);
-    gtk_misc_set_alignment(GTK_MISC(txt_lat), 1.f, 0.5f);
-
-    gtk_table_attach(GTK_TABLE(table),
-            label = gtk_label_new(_("Lon")),
-            0, 1, 1, 2, GTK_FILL, 0, 2, 4);
-    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-    gtk_table_attach(GTK_TABLE(table),
-            txt_lon = gtk_label_new(""),
-            1, 2, 1, 2, GTK_FILL, 0, 2, 4);
-    gtk_misc_set_alignment(GTK_MISC(txt_lon), 1.f, 0.5f);
-
-    gtk_table_attach(GTK_TABLE(table),
-            label = gtk_label_new(_("Format")),
-            0, 1, 2, 3, GTK_FILL, 0, 2, 4);
-    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-    gtk_table_attach(GTK_TABLE(table),
-            label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
-            1, 2, 2, 3, GTK_FILL, 0, 2, 4);
-    gtk_container_add(GTK_CONTAINER(label),
-            cmb_format = gtk_combo_box_new_text());
-    gtk_table_attach(GTK_TABLE(table),
-            btn_copy = gtk_button_new_with_label(_("Copy")),
-            0, 2, 3, 4, GTK_FILL, 0, 2, 4);
-
-    /* Lat/Lon */
-    {
-      gchar buffer[LL_FMT_LEN];
-
-      lat_format(lat, buffer);
-      gtk_label_set_label(GTK_LABEL(txt_lat), buffer);
-      lat_format(lon, buffer);
-      gtk_label_set_label(GTK_LABEL(txt_lon), buffer);
-    }
-
-    /* Fill in formats */
-    {
-      int i;
-
-      for(i = 0; i < DEG_FORMAT_ENUM_COUNT; i++) {
-          gtk_combo_box_append_text(GTK_COMBO_BOX(cmb_format),
-                  DEG_FORMAT_TEXT[i]);
-      }
-      gtk_combo_box_set_active(GTK_COMBO_BOX(cmb_format), _degformat);
-    }
-
-
-    /* setup cb context */
-    lld.fmt_combo = cmb_format;
-    lld.glat = lat;
-    lld.glon = lon;
-    lld.lat = txt_lat;
-    lld.lon = txt_lon;
-
-    /* Connect Signals */
-    g_signal_connect(G_OBJECT(cmb_format), "changed",
-                    G_CALLBACK(latlon_cb_fmt_changed), &lld);
-    g_signal_connect(G_OBJECT(btn_copy), "clicked",
-                    G_CALLBACK(latlon_cb_copy_clicked), &lld);
-
-    gtk_widget_show_all(dialog);
-
-    gtk_dialog_run(GTK_DIALOG(dialog));
-    gtk_widget_hide_all(dialog);
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static void
-cmenu_show_latlon(guint unitx, guint unity)
-{
-  gfloat lat, lon;
-  gchar buffer[80], tmp1[LL_FMT_LEN], tmp2[LL_FMT_LEN];
-  printf("%s()\n", __PRETTY_FUNCTION__);
-
-  unit2latlon(unitx, unity, lat, lon);
-  lat_format(lat, tmp1);
-  lon_format(lon, tmp2);
-
-  snprintf(buffer, sizeof(buffer),
-            "%s: %s\n"
-          "%s: %s",
-          _("Latitude"), tmp1,
-          _("Longitude"), tmp2);
-
-  MACRO_BANNER_SHOW_INFO(_window, buffer);
-
-  vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static void
-cmenu_clip_latlon(guint unitx, guint unity)
-{
-    gchar buffer[80];
-    gfloat lat, lon;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    unit2latlon(unitx, unity, lat, lon);
-
-    snprintf(buffer, sizeof(buffer), "%.06f,%.06f", lat, lon);
-
-    gtk_clipboard_set_text(
-            gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), buffer, -1);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static void
-cmenu_route_to(guint unitx, guint unity)
-{
-    gchar buffer[80];
-    gchar strlat[32];
-    gchar strlon[32];
-    gfloat lat, lon;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    unit2latlon(unitx, unity, lat, lon);
-
-    g_ascii_formatd(strlat, 32, "%.06f", lat);
-    g_ascii_formatd(strlon, 32, "%.06f", lon);
-    snprintf(buffer, sizeof(buffer), "%s, %s", strlat, strlon);
-
-    route_download(buffer);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static void
-cmenu_distance_to(guint unitx, guint unity)
-{
-    gchar buffer[80];
-    gfloat lat, lon;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    unit2latlon(unitx, unity, lat, lon);
-
-    snprintf(buffer, sizeof(buffer), "%s: %.02f %s", _("Distance"),
-            calculate_distance(_gps.lat, _gps.lon, lat, lon)
-              * UNITS_CONVERT[_units],
-            UNITS_TEXT[_units]);
-    MACRO_BANNER_SHOW_INFO(_window, buffer);
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static void
-cmenu_add_route(guint unitx, guint unity)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-    MACRO_PATH_INCREMENT_TAIL(_route);
-    _route.tail->unitx = x2unit(_cmenu_position_x);
-    _route.tail->unity = y2unit(_cmenu_position_y);
-    route_find_nearest_point();
-    map_force_redraw();
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static void
-cmenu_route_add_way(guint unitx, guint unity)
-{
-    gfloat lat, lon;
-    gchar tmp1[LL_FMT_LEN], tmp2[LL_FMT_LEN], *p_latlon;
-    static GtkWidget *dialog = NULL;
-    static GtkWidget *table = NULL;
-    static GtkWidget *label = NULL;
-    static GtkWidget *txt_scroll = NULL;
-    static GtkWidget *txt_desc = NULL;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(dialog == NULL)
-    {
-        dialog = gtk_dialog_new_with_buttons(_("Add Waypoint"),
-                GTK_WINDOW(_window), GTK_DIALOG_MODAL,
-                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
-                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
-                NULL);
-
-        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
-                table = gtk_table_new(2, 2, FALSE), TRUE, TRUE, 0);
-
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("Lat, Lon:")),
-                0, 1, 0, 1, GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-
-        unit2latlon(unitx, unity, lat, lon);
-        lat_format(lat, tmp1);
-        lon_format(lon, tmp2);
-        p_latlon = g_strdup_printf("%s, %s", tmp1, tmp2);
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(p_latlon),
-                1, 2, 0, 1, GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
-        g_free(p_latlon);
-
-        gtk_table_attach(GTK_TABLE(table),
-                label = gtk_label_new(_("Description")),
-                0, 1, 1, 2, GTK_FILL, 0, 2, 4);
-        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
-
-        txt_scroll = gtk_scrolled_window_new(NULL, NULL);
-        gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(txt_scroll),
-                                       GTK_SHADOW_IN);
-        gtk_table_attach(GTK_TABLE(table),
-                txt_scroll,
-                1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
-
-        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(txt_scroll),
-                GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-
-        txt_desc = gtk_text_view_new ();
-        gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt_desc), GTK_WRAP_WORD);
-
-        gtk_container_add(GTK_CONTAINER(txt_scroll), txt_desc);
-        gtk_widget_set_size_request(GTK_WIDGET(txt_scroll), 400, 60);
-    }
-
-    gtk_text_buffer_set_text(
-            gtk_text_view_get_buffer(GTK_TEXT_VIEW(txt_desc)), "", 0);
-
-    gtk_widget_show_all(dialog);
-
-    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
-    {
-        GtkTextBuffer *tbuf;
-        GtkTextIter ti1, ti2;
-        gchar *desc;
-
-        tbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txt_desc));
-        gtk_text_buffer_get_iter_at_offset(tbuf, &ti1, 0);
-        gtk_text_buffer_get_end_iter(tbuf, &ti2);
-        desc = gtk_text_buffer_get_text(tbuf, &ti1, &ti2, TRUE);
-
-        if(*desc)
-        {
-            /* There's a description.  Add a waypoint. */
-            MACRO_PATH_INCREMENT_TAIL(_route);
-            _route.tail->unitx = unitx;
-            _route.tail->unity = unity;
-            _route.tail->time = 0;
-            _route.tail->altitude = NAN;
-
-            MACRO_PATH_INCREMENT_WTAIL(_route);
-            _route.wtail->point = _route.tail;
-            _route.wtail->desc
-                = gtk_text_buffer_get_text(tbuf, &ti1, &ti2, TRUE);
-        }
-        else
-        {
-            GtkWidget *confirm;
-
-            g_free(desc);
-
-            confirm = hildon_note_new_confirmation(GTK_WINDOW(dialog),
-                    _("Creating a \"waypoint\" with no description actually "
-                        "adds a break point.  Is that what you want?"));
-
-            if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm)))
-            {
-                /* There's no description.  Add a break by adding a (0, 0)
-                 * point (if necessary), and then the ordinary route point. */
-                if(_route.tail->unity)
-                {
-                    MACRO_PATH_INCREMENT_TAIL(_route);
-                    *_route.tail = _point_null;
-                }
-
-                MACRO_PATH_INCREMENT_TAIL(_route);
-                _route.tail->unitx = unitx;
-                _route.tail->unity = unity;
-                _route.tail->time = 0;
-                _route.tail->altitude = NAN;
-
-
-                gtk_widget_destroy(confirm);
-            }
-            else
-            {
-                gtk_widget_destroy(confirm);
-                continue;
-            }
-        }
-
-        route_find_nearest_point();
-        map_render_paths();
-        MACRO_QUEUE_DRAW_AREA();
-        break;
-    }
-    gtk_widget_hide(dialog);
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-static gboolean
-cmenu_cb_loc_show_latlon(GtkAction *action)
-{
-    gdouble lat, lon;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    unit2latlon(x2unit(_cmenu_position_x),
-            y2unit(_cmenu_position_y),
-            lat, lon);
-
-    latlon_dialog(lat, lon);
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-cmenu_cb_loc_route_to(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    cmenu_route_to(
-            x2unit(_cmenu_position_x),
-            y2unit(_cmenu_position_y));
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-cmenu_cb_loc_distance_to(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    cmenu_distance_to(
-            x2unit(_cmenu_position_x),
-            y2unit(_cmenu_position_y));
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-cmenu_cb_loc_add_route(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    cmenu_add_route(
-            x2unit(_cmenu_position_x),
-            y2unit(_cmenu_position_y));
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-cmenu_cb_loc_add_way(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    cmenu_route_add_way(
-            x2unit(_cmenu_position_x),
-            y2unit(_cmenu_position_y));
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-cmenu_cb_loc_add_poi(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    poi_dialog(ACTION_ADD_POI,
-            x2unit(_cmenu_position_x),
-            y2unit(_cmenu_position_y));
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-cmenu_cb_loc_set_gps(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    _pos.unitx = x2unit(_cmenu_position_x);
-    _pos.unity = y2unit(_cmenu_position_y);
-    unit2latlon(_pos.unitx, _pos.unity, _gps.lat, _gps.lon);
-
-    /* Move mark to new location. */
-    refresh_mark();
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static WayPoint *
-find_nearest_waypoint(guint unitx, guint unity)
-{
-    WayPoint *wcurr;
-    WayPoint *wnear;
-    guint64 nearest_squared;
-    Point pos = { unitx, unity, 0, NAN };
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    wcurr = wnear = _route.whead;
-    if(wcurr && wcurr != _route.wtail)
-    {
-        nearest_squared = DISTANCE_SQUARED(pos, *(wcurr->point));
-
-        while(wcurr++ != _route.wtail)
-        {
-            guint64 test_squared = DISTANCE_SQUARED(pos, *(wcurr->point));
-            if(test_squared < nearest_squared)
-            {
-                wnear = wcurr;
-                nearest_squared = test_squared;
-            }
-        }
-    }
-
-    if(wnear)
-    {
-        /* Only use the waypoint if it is within a 6*_draw_width square drawn
-         * around the position. This is consistent with select_poi(). */
-        if(abs(unitx - wnear->point->unitx) < pixel2unit(3 * _draw_width)
-            && abs(unity - wnear->point->unity) < pixel2unit(3 * _draw_width))
-            return wnear;
-    }
-
-    MACRO_BANNER_SHOW_INFO(_window, _("There are no waypoints."));
-
-    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-    return NULL;
-}
-
-static gboolean
-cmenu_cb_way_show_latlon(GtkAction *action)
-{
-    WayPoint *way;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if((way = find_nearest_waypoint(
-            x2unit(_cmenu_position_x),
-            y2unit(_cmenu_position_y))))
-        cmenu_show_latlon(way->point->unitx, way->point->unity);
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-cmenu_cb_way_show_desc(GtkAction *action)
-{
-    WayPoint *way;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if((way = find_nearest_waypoint(
-            x2unit(_cmenu_position_x),
-            y2unit(_cmenu_position_y))))
-    {
-        MACRO_BANNER_SHOW_INFO(_window, way->desc);
-    }
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-cmenu_cb_way_clip_latlon(GtkAction *action)
-{
-    WayPoint *way;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if((way = find_nearest_waypoint(
-            x2unit(_cmenu_position_x),
-            y2unit(_cmenu_position_y))))
-        cmenu_clip_latlon(way->point->unitx, way->point->unity);
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-cmenu_cb_way_clip_desc(GtkAction *action)
-{
-    WayPoint *way;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if((way = find_nearest_waypoint(
-            x2unit(_cmenu_position_x),
-            y2unit(_cmenu_position_y))))
-        gtk_clipboard_set_text(
-                gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), way->desc, -1);
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-cmenu_cb_way_route_to(GtkAction *action)
-{
-    WayPoint *way;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if((way = find_nearest_waypoint(
-            x2unit(_cmenu_position_x),
-            y2unit(_cmenu_position_y))))
-        cmenu_route_to(way->point->unitx, way->point->unity);
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-cmenu_cb_way_distance_to(GtkAction *action)
-{
-    WayPoint *way;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if((way = find_nearest_waypoint(
-            x2unit(_cmenu_position_x),
-            y2unit(_cmenu_position_y))))
-        route_show_distance_to(way->point);
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-cmenu_cb_way_delete(GtkAction *action)
-{
-    WayPoint *way;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if((way = find_nearest_waypoint(
-            x2unit(_cmenu_position_x),
-            y2unit(_cmenu_position_y))))
-    {
-        gchar buffer[BUFFER_SIZE];
-        GtkWidget *confirm;
-
-        snprintf(buffer, sizeof(buffer), "%s:\n%s\n",
-                _("Confirm delete of waypoint"), way->desc);
-        confirm = hildon_note_new_confirmation(GTK_WINDOW(_window), buffer);
-
-        if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm)))
-        {
-            Point *pdel_min, *pdel_max, *pdel_start, *pdel_end;
-            guint num_del;
-
-            /* Delete surrounding route data, too. */
-            if(way == _route.whead)
-                pdel_min = _route.head;
-            else
-                pdel_min = way[-1].point;
-
-            if(way == _route.wtail)
-                pdel_max = _route.tail;
-            else
-                pdel_max = way[1].point;
-
-            /* Find largest continuous segment around the waypoint, EXCLUDING
-             * pdel_min and pdel_max. */
-            for(pdel_start = way->point - 1; pdel_start->unity
-                    && pdel_start > pdel_min; pdel_start--) { }
-            for(pdel_end = way->point + 1; pdel_end->unity
-                    && pdel_end < pdel_max; pdel_end++) { }
-
-            /* If pdel_end is set to _route.tail, and if _route.tail is a
-             * non-zero point, then delete _route.tail. */
-            if(pdel_end == _route.tail && pdel_end->unity)
-                pdel_end++; /* delete _route.tail too */
-            /* else, if *both* endpoints are zero points, delete one. */
-            else if(!pdel_start->unity && !pdel_end->unity)
-                pdel_start--;
-
-            /* Delete BETWEEN pdel_start and pdel_end, exclusive. */
-            num_del = pdel_end - pdel_start - 1;
-
-            memmove(pdel_start + 1, pdel_end,
-                    (_route.tail - pdel_end + 1) * sizeof(Point));
-            _route.tail -= num_del;
-
-            /* Remove waypoint and move/adjust subsequent waypoints. */
-            g_free(way->desc);
-            while(way++ != _route.wtail)
-            {
-                way[-1] = *way;
-                way[-1].point -= num_del;
-            }
-            _route.wtail--;
-
-            route_find_nearest_point();
-            map_force_redraw();
-        }
-        gtk_widget_destroy(confirm);
-    }
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-cmenu_cb_way_add_poi(GtkAction *action)
-{
-    WayPoint *way;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if((way = find_nearest_waypoint(
-            x2unit(_cmenu_position_x),
-            y2unit(_cmenu_position_y))))
-        poi_dialog(ACTION_ADD_POI, way->point->unitx, way->point->unity);
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-cmenu_cb_poi_route_to(GtkAction *action)
-{
-    PoiInfo poi;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(select_poi(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y), &poi,
-                FALSE)) /* FALSE = not quick */
-    {
-        guint unitx, unity;
-        latlon2unit(poi.lat, poi.lon, unitx, unity);
-        cmenu_route_to(unitx, unity);
-    }
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-cmenu_cb_poi_distance_to(GtkAction *action)
-{
-    PoiInfo poi;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(select_poi(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y), &poi,
-            FALSE)) /* FALSE = not quick */
-    {
-        guint unitx, unity;
-        latlon2unit(poi.lat, poi.lon, unitx, unity);
-        cmenu_distance_to(unitx, unity);
-    }
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-cmenu_cb_poi_add_route(GtkAction *action)
-{
-    PoiInfo poi;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(select_poi(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y), &poi,
-            FALSE)) /* FALSE = not quick */
-    {
-        guint unitx, unity;
-        latlon2unit(poi.lat, poi.lon, unitx, unity);
-        cmenu_add_route(unitx, unity);
-    }
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-cmenu_cb_poi_add_way(GtkAction *action)
-{
-    PoiInfo poi;
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    if(select_poi(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y), &poi,
-            FALSE)) /* FALSE = not quick */
-    {
-        guint unitx, unity;
-        latlon2unit(poi.lat, poi.lon, unitx, unity);
-        cmenu_route_add_way(unitx, unity);
-    }
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-static gboolean
-cmenu_cb_poi_edit_poi(GtkAction *action)
-{
-    printf("%s()\n", __PRETTY_FUNCTION__);
-
-    poi_dialog(ACTION_EDIT_POI,
-            x2unit(_cmenu_position_x), y2unit(_cmenu_position_y));
-
-    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
-    return TRUE;
-}
-
-/****************************************************************************
- * ABOVE: CALLBACKS *********************************************************
- ****************************************************************************/
-
-/* Utility function to parse DMS values */
-
-/*
- * Get one numeric token off the string, fractional part separator
- * is ',' or '.' and number may follow any token from sep.
- * Return value found is in d.
- *
- * If utf8_deg is set then accept also Unicode degree symbol U+00B0
- * encoded as UTF-8 octets 0xc2 0xb0.
- *
- * @returns
- *    0 : on error.
- *    1 : when nothing or just white space was seen.
- *    2 : when fractional number was seen.
- *    3 : when whole number was seen.
- *  In case 0, endptr points to the beginning of the input string nptr,
- *  d is undefined.
- *
- *  In case 1 endptr points past the whitespace, d is undefined.
- *
- *  In cases 2 and 3 the found number is stored in d and endptr points
- *  to first char not part of the number.
- *
- */
-static gint
-strdmstod_1(gdouble *d, gchar *nptr, gchar **endptr, gchar *sep, gint utf8_deg)
-{
-    guchar *p;
-    gint v_flag, f_flag;
-    gdouble v;
-
-    p = nptr;
-
-    while (*p && isspace(*p)) {
-        p++;
-    }
-
-    v_flag = 0;
-    f_flag = 0;
-
-    /* whole part */
-    v = 0.0;
-    while (*p && isdigit(*p)) {
-        v *= 10;
-        v += *p++ - '0';
-        v_flag = 1;
-    }
-
-    if (v_flag) {
-        if (*p && (*p == '.' || *p == ',')) {
-            gdouble f;
-            gint n;
-
-            p++;
-
-            /* fractional part */
-            f = 0.0;
-            n = 1;
-            while (*p && isdigit(*p)) {
-                f *= 10.0;
-                f += *p++ - '0';
-                n *= 10;
-            }
-
-            if (n > 1) {
-                f_flag = 1;
-                v += f/n;
-            }
-        }
-
-        /* allow for extra sep char at the end */
-        if (*p && strchr(sep, *p)) {
-            p++;
-        } else if (utf8_deg && *p == 0xc2 && *(p+1) == 0xb0) {
-            p += 2;
-        }
-
-        *d = v;
-        if (endptr) *endptr = p;
-        return f_flag ? 2 : 3;
-    }
-
-    if (endptr) *endptr = p;
-    return *p == 0;
-}
-
-static gdouble
-strdmstod_2(gchar *nptr, gchar **endptr)
-{
-    gint ret;
-    guchar *p;
-    gdouble d, m, s;
-
-    p = nptr;
-
-    /* degrees */
-    ret = strdmstod_1(&d, p, endptr, "dD@", 1);
-    switch (ret) {
-        case 0: return 0.0;
-        case 1:
-                if (endptr) *endptr = (char *)nptr;
-                return 0.0;
-        case 2: return d;
-    }
-
-    /* minutes */
-    p = *endptr;
-    m = 0.0;
-    ret = strdmstod_1(&m, p, endptr, "mM'", 0);
-    switch (ret) {
-        case 0: return 0.0;
-        case 1: return d;
-        case 2: return d + m/60.0;
-    }
-
-    /* seconds */
-    p = *endptr;
-    ret = strdmstod_1(&s, p, endptr, "sS\"", 0);
-    switch (ret) {
-        case 0: return 0.0;
-        case 1: return d + m/60.0;
-        case 2:
-        case 3: return d + m/60.0 + s/3600.0;
-    }
-
-    /* can't be here */
-    return 0.0;
-}
-
-/*
- * format: / \s* [+-NSWE]? \s* ( d | D \s+ m | D \s+ M \s+ s ) [NSWE]? /x
- * where D := / \d+[@d°]? /ix
- *       M := / \d+['m]? /ix
- *       d := / D | \d+[,.]\d+[@d°]? /ix
- *       m := / M | \d+[,.]\d+['m]? /ix
- *       s := / S | \d+[,.]\d+["s]? /ix
- *
- *   and N or W are treated as positive, S or E are treated as negative,
- *   they may occur only once.
- */
-static gdouble
-strdmstod(const gchar *nptr, gchar **endptr)
-{
-    gint s;
-    gchar *p, *end;
-    gchar *sign = 0;
-    gdouble d;
-
-    p = (char *)nptr;
-
-    while (*p && isspace(*p))
-        p++;
-
-    if (!*p) {
-        if (endptr) *endptr = (char *)nptr;
-        return 0.0;
-    }
-
-    if (strchr("NWSE-+", *p)) {
-        sign = p;
-        p++;
-    }
-
-    d = strdmstod_2(p, &end);
-    if (p == end && d == 0.0) {
-        if (endptr) *endptr = end;
-        return d;
-    }
-
-    p = end;
-    while (*p && isspace(*p))
-        p++;
-
-    s = 1;
-    if (sign == 0) {
-        if (*p && strchr("NWSE", *p)) {
-            if (*p == 'S' || *p == 'E') s = -1;
-            p++;
-        }
-    } else {
-        if (*sign == 'S' || *sign == 'E' || *sign == '-') s = -1;
-    }
-
-    if (endptr) *endptr = p;
-    return s * d;
-}
-
-#if 0
-struct t_case {
-    gchar *fmt;
-    gdouble value;
-} t_cases[] = {
-    { "12°", 12 },
-    { "+12d", 12 },
-    { "-12.345d", -12.345 },
-    { "12.345 E", -12.345 },
-    { "12d34m", 12.5666667 },
-    { "N 12 34", 12.5666667 },
-    { "S 12d34.56m", -12.576 },
-    { "W 12 34.56", 12.576 },
-    { "E 12d34m56s", -12.582222 },
-    { "12 34 56 S", -12.582222 },
-    { "12 34 56", 12.582222 },
-    { "12d34m56.7s E", -12.582417 },
-    { "12 34 56.7 W", 12.582417 },
-    { "12° 34 56.7 W", 12.582417 },
-
-    { 0, 0 }
-};
-
-int
-strdmstod_test()
-{
-    struct t_case *t;
-    gint fail, ok;
-
-    fail = ok = 0;
-
-    for (t = t_cases; t->fmt; t++) {
-        gdouble v;
-        gchar *endp;
-
-        v = strdmstod(t->fmt, &endp);
-        if (endp == t->fmt || *endp != 0) {
-            fprintf(stderr, "FAIL syntax %s\n", t->fmt);
-            fail++;
-        } else if (fabs(v - t->value) > 0.000001) {
-            fprintf(stderr, "FAIL value %s -> %.10g (%.10g)\n",
-                    t->fmt, v, t->value);
-            fail++;
-        } else {
-            ok++;
-        }
-    }
-
-    if (fail == 0) {
-        fprintf(stderr, "ALL TESTS OK\n");
-    } else {
-        fprintf(stderr, "FAIL %d, OK %d\n", fail, ok);
-    }
-}
-#endif
diff --git a/src/main.c b/src/main.c
new file mode 100644 (file)
index 0000000..ecaa652
--- /dev/null
@@ -0,0 +1,616 @@
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define _GNU_SOURCE
+
+#include <config.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <hildon-widgets/hildon-program.h>
+#include <hildon-widgets/hildon-banner.h>
+#include <gconf/gconf-client.h>
+#include <device_symbols.h>
+#include <conicconnection.h>
+#include <conicconnectionevent.h>
+
+#include <locale.h>
+
+#include "types.h"
+#include "data.h"
+#include "defines.h"
+
+#include "cmenu.h"
+#include "display.h"
+#include "gps.h"
+#include "gpx.h"
+#include "input.h"
+#include "main.h"
+#include "maps.h"
+#include "menu.h"
+#include "path.h"
+#include "poi.h"
+#include "settings.h"
+#include "util.h"
+
+static void osso_cb_hw_state(osso_hw_state_t *state, gpointer data);
+
+static HildonProgram *_program = NULL;
+
+static ConIcConnection *_conic_conn = NULL;
+static gboolean _conic_is_connecting = FALSE;
+static volatile gboolean _conic_is_connected = FALSE;
+static GMutex *_conic_is_connected_mutex = NULL;
+static GCond *_conic_is_connected_cond = NULL;
+
+static void
+conic_conn_event(ConIcConnection *connection, ConIcConnectionEvent *event)
+{
+    ConIcConnectionStatus status;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    g_mutex_lock(_conic_is_connected_mutex);
+
+    status = con_ic_connection_event_get_status(event);
+
+    if((_conic_is_connected = (status == CON_IC_CONNECTION_ERROR_NONE)))
+    {
+        /* We're connected. */
+        if(_download_banner != NULL)
+        {
+            gtk_widget_show(_download_banner);
+        }
+    }
+    else
+    {
+        /* We're not connected. */
+        if(_download_banner != NULL)
+        {
+            gtk_widget_hide(_download_banner);
+        }
+    }
+
+    _conic_is_connecting = FALSE; /* No longer trying to connect. */
+    g_cond_broadcast(_conic_is_connected_cond);
+    g_mutex_unlock(_conic_is_connected_mutex);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+void
+conic_recommend_connected()
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+#ifndef DEBUG
+    g_mutex_lock(_conic_is_connected_mutex);
+    if(!_conic_is_connecting)
+    {
+        /* Fire up a connection request. */
+        con_ic_connection_connect(_conic_conn, CON_IC_CONNECT_FLAG_NONE);
+        _conic_is_connecting = TRUE;
+    }
+    g_mutex_unlock(_conic_is_connected_mutex);
+#endif
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+void
+conic_ensure_connected()
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+#ifndef DEBUG
+    while(!_conic_is_connected)
+    {   
+        g_mutex_lock(_conic_is_connected_mutex);
+        if(!_conic_is_connecting)
+        {
+            /* Fire up a connection request. */
+            con_ic_connection_connect(_conic_conn, CON_IC_CONNECT_FLAG_NONE);
+            _conic_is_connecting = TRUE;
+        }
+        g_cond_wait(_conic_is_connected_cond, _conic_is_connected_mutex);
+        g_mutex_unlock(_conic_is_connected_mutex);
+    }
+#endif
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+/**
+ * Save state and destroy all non-UI elements created by this program in
+ * preparation for exiting.
+ */
+static void
+maemo_mapper_destroy()
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    /* _program and widgets have already been destroyed. */
+    _window = NULL;
+
+    path_destroy();
+
+    settings_save();
+
+    poi_destroy();
+
+    if(_curr_repo->db)
+    {
+#ifdef MAPDB_SQLITE
+        g_mutex_lock(_mapdb_mutex);
+        sqlite3_close(_curr_repo->db);
+        _curr_repo->db = NULL;
+        g_mutex_unlock(_mapdb_mutex);
+#else
+        g_mutex_lock(_mapdb_mutex);
+        gdbm_close(_curr_repo->db);
+        _curr_repo->db = NULL;
+        g_mutex_unlock(_mapdb_mutex);
+#endif
+    }
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+/**
+ * Initialize everything required in preparation for calling gtk_main().
+ */
+static void
+maemo_mapper_init(gint argc, gchar **argv)
+{
+    GtkWidget *hbox, *label, *vbox;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    /* Set enum-based constants. */
+    UNITS_ENUM_TEXT[UNITS_KM] = _("km");
+    UNITS_ENUM_TEXT[UNITS_MI] = _("mi.");
+    UNITS_ENUM_TEXT[UNITS_NM] = _("n.m.");
+
+    ROTATE_DIR_ENUM_TEXT[ROTATE_DIR_UP] = _("Up");
+    ROTATE_DIR_ENUM_TEXT[ROTATE_DIR_RIGHT] = _("Right");
+    ROTATE_DIR_ENUM_TEXT[ROTATE_DIR_DOWN] = _("Down");
+    ROTATE_DIR_ENUM_TEXT[ROTATE_DIR_LEFT] = _("Left");
+
+    UNBLANK_ENUM_TEXT[UNBLANK_WITH_GPS] = "When Receiving Any GPS Data";
+    UNBLANK_ENUM_TEXT[UNBLANK_WHEN_MOVING] = "When Moving";
+    UNBLANK_ENUM_TEXT[UNBLANK_FULLSCREEN] = "When Moving (Full Screen Only)";
+    UNBLANK_ENUM_TEXT[UNBLANK_WAYPOINT] = "When Approaching a Waypoint";
+    UNBLANK_ENUM_TEXT[UNBLANK_NEVER] = "Never";
+
+    INFO_FONT_ENUM_TEXT[INFO_FONT_XXSMALL] = "xx-small";
+    INFO_FONT_ENUM_TEXT[INFO_FONT_XSMALL] = "x-small";
+    INFO_FONT_ENUM_TEXT[INFO_FONT_SMALL] = "small";
+    INFO_FONT_ENUM_TEXT[INFO_FONT_MEDIUM] = "medium";
+    INFO_FONT_ENUM_TEXT[INFO_FONT_LARGE] = "large";
+    INFO_FONT_ENUM_TEXT[INFO_FONT_XLARGE] = "x-large";
+    INFO_FONT_ENUM_TEXT[INFO_FONT_XXLARGE] = "xx-large";
+
+    CUSTOM_KEY_GCONF[CUSTOM_KEY_UP] = GCONF_KEY_PREFIX"/key_up";
+    CUSTOM_KEY_GCONF[CUSTOM_KEY_DOWN] = GCONF_KEY_PREFIX"/key_down";
+    CUSTOM_KEY_GCONF[CUSTOM_KEY_LEFT] = GCONF_KEY_PREFIX"/key_left";
+    CUSTOM_KEY_GCONF[CUSTOM_KEY_RIGHT] = GCONF_KEY_PREFIX"/key_right";
+    CUSTOM_KEY_GCONF[CUSTOM_KEY_SELECT] = GCONF_KEY_PREFIX"/key_select";
+    CUSTOM_KEY_GCONF[CUSTOM_KEY_INCREASE] = GCONF_KEY_PREFIX"/key_increase";
+    CUSTOM_KEY_GCONF[CUSTOM_KEY_DECREASE] = GCONF_KEY_PREFIX"/key_decrease";
+    CUSTOM_KEY_GCONF[CUSTOM_KEY_FULLSCREEN]= GCONF_KEY_PREFIX"/key_fullscreen";
+    CUSTOM_KEY_GCONF[CUSTOM_KEY_ESC] = GCONF_KEY_PREFIX"/key_esc";
+
+    CUSTOM_KEY_ICON[CUSTOM_KEY_UP] = HWK_BUTTON_UP;
+    CUSTOM_KEY_ICON[CUSTOM_KEY_LEFT] = HWK_BUTTON_LEFT;
+    CUSTOM_KEY_ICON[CUSTOM_KEY_DOWN] = HWK_BUTTON_DOWN;
+    CUSTOM_KEY_ICON[CUSTOM_KEY_RIGHT] = HWK_BUTTON_RIGHT;
+    CUSTOM_KEY_ICON[CUSTOM_KEY_SELECT] = HWK_BUTTON_SELECT;
+    CUSTOM_KEY_ICON[CUSTOM_KEY_INCREASE] = HWK_BUTTON_INCREASE;
+    CUSTOM_KEY_ICON[CUSTOM_KEY_DECREASE] = HWK_BUTTON_DECREASE;
+    CUSTOM_KEY_ICON[CUSTOM_KEY_FULLSCREEN] = HWK_BUTTON_VIEW;
+    CUSTOM_KEY_ICON[CUSTOM_KEY_ESC] = HWK_BUTTON_CANCEL;
+
+    CUSTOM_KEY_DEFAULT[CUSTOM_KEY_UP] = CUSTOM_ACTION_RESET_VIEW_ANGLE;
+    CUSTOM_KEY_DEFAULT[CUSTOM_KEY_LEFT] =CUSTOM_ACTION_ROTATE_COUNTERCLOCKWISE;
+    CUSTOM_KEY_DEFAULT[CUSTOM_KEY_DOWN] = CUSTOM_ACTION_TOGGLE_AUTOROTATE;
+    CUSTOM_KEY_DEFAULT[CUSTOM_KEY_RIGHT] = CUSTOM_ACTION_ROTATE_CLOCKWISE;
+    CUSTOM_KEY_DEFAULT[CUSTOM_KEY_SELECT] = CUSTOM_ACTION_TOGGLE_AUTOCENTER;
+    CUSTOM_KEY_DEFAULT[CUSTOM_KEY_INCREASE] = CUSTOM_ACTION_ZOOM_IN;
+    CUSTOM_KEY_DEFAULT[CUSTOM_KEY_DECREASE] = CUSTOM_ACTION_ZOOM_OUT;
+    CUSTOM_KEY_DEFAULT[CUSTOM_KEY_FULLSCREEN]= CUSTOM_ACTION_TOGGLE_FULLSCREEN;
+    CUSTOM_KEY_DEFAULT[CUSTOM_KEY_ESC] = CUSTOM_ACTION_TOGGLE_TRACKS;
+
+    CUSTOM_ACTION_ENUM_TEXT[CUSTOM_ACTION_PAN_NORTH] = _("Pan North");
+    CUSTOM_ACTION_ENUM_TEXT[CUSTOM_ACTION_PAN_WEST] = _("Pan West");
+    CUSTOM_ACTION_ENUM_TEXT[CUSTOM_ACTION_PAN_SOUTH] = _("Pan South");
+    CUSTOM_ACTION_ENUM_TEXT[CUSTOM_ACTION_PAN_EAST] = _("Pan East");
+    CUSTOM_ACTION_ENUM_TEXT[CUSTOM_ACTION_RESET_VIEW_ANGLE]
+        = _("Reset Viewing Angle");
+    CUSTOM_ACTION_ENUM_TEXT[CUSTOM_ACTION_ROTATE_CLOCKWISE]
+        = _("Rotate View Clockwise");
+    CUSTOM_ACTION_ENUM_TEXT[CUSTOM_ACTION_ROTATE_COUNTERCLOCKWISE]
+        = _("Rotate View Counter-Clockwise");
+    CUSTOM_ACTION_ENUM_TEXT[CUSTOM_ACTION_TOGGLE_AUTOCENTER]
+        = _("Toggle Auto-Center");
+    CUSTOM_ACTION_ENUM_TEXT[CUSTOM_ACTION_TOGGLE_AUTOROTATE]
+        = _("Toggle Auto-Rotate");
+    CUSTOM_ACTION_ENUM_TEXT[CUSTOM_ACTION_TOGGLE_FULLSCREEN]
+        = _("Toggle Fullscreen");
+    CUSTOM_ACTION_ENUM_TEXT[CUSTOM_ACTION_ZOOM_IN] = _("Zoom In");
+    CUSTOM_ACTION_ENUM_TEXT[CUSTOM_ACTION_ZOOM_OUT] = _("Zoom Out");
+    CUSTOM_ACTION_ENUM_TEXT[CUSTOM_ACTION_TOGGLE_TRACKS] = _("Toggle Tracks");
+    CUSTOM_ACTION_ENUM_TEXT[CUSTOM_ACTION_TOGGLE_SCALE] = _("Toggle Scale");
+    CUSTOM_ACTION_ENUM_TEXT[CUSTOM_ACTION_TOGGLE_POI] = _("Toggle POIs");
+    CUSTOM_ACTION_ENUM_TEXT[CUSTOM_ACTION_CHANGE_REPO]= _("Select Next Repository");
+    CUSTOM_ACTION_ENUM_TEXT[CUSTOM_ACTION_ROUTE_DISTNEXT]
+        = _("Show Distance to Next Waypoint");
+    CUSTOM_ACTION_ENUM_TEXT[CUSTOM_ACTION_ROUTE_DISTLAST]
+        = _("Show Distance to End of Route");
+    CUSTOM_ACTION_ENUM_TEXT[CUSTOM_ACTION_TRACK_BREAK] = _("Insert Track Break");
+    CUSTOM_ACTION_ENUM_TEXT[CUSTOM_ACTION_TRACK_CLEAR] = _("Clear Track");
+    CUSTOM_ACTION_ENUM_TEXT[CUSTOM_ACTION_TRACK_DISTLAST]
+        = _("Show Distance from Last Break");
+    CUSTOM_ACTION_ENUM_TEXT[CUSTOM_ACTION_TRACK_DISTFIRST]
+        = _("Show Distance from Beginning");
+    CUSTOM_ACTION_ENUM_TEXT[CUSTOM_ACTION_TOGGLE_GPS] = _("Toggle GPS");
+    CUSTOM_ACTION_ENUM_TEXT[CUSTOM_ACTION_TOGGLE_GPSINFO] = _("Toggle GPS Info");
+    CUSTOM_ACTION_ENUM_TEXT[CUSTOM_ACTION_TOGGLE_SPEEDLIMIT]
+        = _("Toggle Speed Limit");
+    CUSTOM_ACTION_ENUM_TEXT[CUSTOM_ACTION_RESET_BLUETOOTH] = _("Reset Bluetooth");
+
+    COLORABLE_GCONF[COLORABLE_MARK] = GCONF_KEY_PREFIX"/color_mark";
+    COLORABLE_GCONF[COLORABLE_MARK_VELOCITY]
+        = GCONF_KEY_PREFIX"/color_mark_velocity";
+    COLORABLE_GCONF[COLORABLE_MARK_OLD] = GCONF_KEY_PREFIX"/color_mark_old";
+    COLORABLE_GCONF[COLORABLE_TRACK] = GCONF_KEY_PREFIX"/color_track";
+    COLORABLE_GCONF[COLORABLE_TRACK_MARK] =GCONF_KEY_PREFIX"/color_track_mark";
+    COLORABLE_GCONF[COLORABLE_TRACK_BREAK]
+        = GCONF_KEY_PREFIX"/color_track_break";
+    COLORABLE_GCONF[COLORABLE_ROUTE] = GCONF_KEY_PREFIX"/color_route";
+    COLORABLE_GCONF[COLORABLE_ROUTE_WAY] = GCONF_KEY_PREFIX"/color_route_way";
+    COLORABLE_GCONF[COLORABLE_ROUTE_BREAK]
+        = GCONF_KEY_PREFIX"/color_route_break";
+    COLORABLE_GCONF[COLORABLE_POI] = GCONF_KEY_PREFIX"/color_poi";
+
+    DEG_FORMAT_ENUM_TEXT[DDPDDDDD] = "-dd.ddddd°";
+    DEG_FORMAT_ENUM_TEXT[DD_MMPMMM] = "-dd°mm.mmm'";
+    DEG_FORMAT_ENUM_TEXT[DD_MM_SSPS] = "-dd°mm'ss.s\"";
+    DEG_FORMAT_ENUM_TEXT[DDPDDDDD_NSEW] = "dd.ddddd° S";
+    DEG_FORMAT_ENUM_TEXT[DD_MMPMMM_NSEW] = "dd°mm.mmm' S";
+    DEG_FORMAT_ENUM_TEXT[DD_MM_SSPS_NSEW] = "dd°mm'ss.s\" S";
+    DEG_FORMAT_ENUM_TEXT[NSEW_DDPDDDDD] = "S dd.ddddd°";
+    DEG_FORMAT_ENUM_TEXT[NSEW_DD_MMPMMM] = "S dd° mm.mmm'";
+    DEG_FORMAT_ENUM_TEXT[NSEW_DD_MM_SSPS] = "S dd° mm' ss.s\"";
+
+    SPEED_LOCATION_ENUM_TEXT[SPEED_LOCATION_TOP_LEFT] = _("Top-Left");
+    SPEED_LOCATION_ENUM_TEXT[SPEED_LOCATION_TOP_RIGHT] = _("Top-Right");
+    SPEED_LOCATION_ENUM_TEXT[SPEED_LOCATION_BOTTOM_RIGHT] = _("Bottom-Right");
+    SPEED_LOCATION_ENUM_TEXT[SPEED_LOCATION_BOTTOM_LEFT] = _("Bottom-Left");
+
+    GPS_RCVR_ENUM_TEXT[GPS_RCVR_NONE] = _("None");
+    GPS_RCVR_ENUM_TEXT[GPS_RCVR_BT] = _("Bluetooth");
+    GPS_RCVR_ENUM_TEXT[GPS_RCVR_GPSD] = _("GPSD");
+    GPS_RCVR_ENUM_TEXT[GPS_RCVR_FILE] = _("File");
+
+    /* Set up track array (must be done before config). */
+    memset(&_track, 0, sizeof(_track));
+    memset(&_route, 0, sizeof(_route));
+    MACRO_PATH_INIT(_track);
+    MACRO_PATH_INIT(_route);
+
+    _mapdb_mutex = g_mutex_new();
+    _mut_priority_mutex = g_mutex_new();
+    _mouse_mutex = g_mutex_new();
+
+    _conic_is_connected_mutex = g_mutex_new();
+    _conic_is_connected_cond = g_cond_new();
+
+    settings_init();
+
+    /* Initialize _program. */
+    _program = HILDON_PROGRAM(hildon_program_get_instance());
+    g_set_application_name("Maemo Mapper");
+
+    /* Initialize _window. */
+    _window = GTK_WIDGET(hildon_window_new());
+    hildon_program_add_window(_program, HILDON_WINDOW(_window));
+
+    /* Lets go fullscreen if so requested in saved config */
+    if (_fullscreen) {
+      gtk_window_fullscreen(GTK_WINDOW(_window));
+    }
+
+    /* Create and add widgets and supporting data. */
+    hbox = gtk_hbox_new(FALSE, 0);
+    gtk_container_add(GTK_CONTAINER(_window), hbox);
+
+    _gps_widget = gtk_frame_new("GPS Info");
+    gtk_container_add(GTK_CONTAINER(_gps_widget),
+            vbox = gtk_vbox_new(FALSE, 0));
+    gtk_widget_set_size_request(GTK_WIDGET(_gps_widget), 180, 0);
+    gtk_box_pack_start(GTK_BOX(hbox), _gps_widget, FALSE, TRUE, 0);
+
+    label = gtk_label_new(" ");
+    gtk_widget_set_size_request(GTK_WIDGET(label), -1, 10);
+    gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 0);
+
+    _text_lat = gtk_label_new(" --- ");
+    gtk_widget_set_size_request(GTK_WIDGET(_text_lat), -1, 30);
+    gtk_box_pack_start(GTK_BOX(vbox), _text_lat, FALSE, TRUE, 0);
+
+    _text_lon = gtk_label_new(" --- ");
+    gtk_widget_set_size_request(GTK_WIDGET(_text_lon), -1, 30);
+    gtk_box_pack_start(GTK_BOX(vbox), _text_lon, FALSE, TRUE, 0);
+
+    _text_speed = gtk_label_new(" --- ");
+    gtk_widget_set_size_request(GTK_WIDGET(_text_speed), -1, 30);
+    gtk_box_pack_start(GTK_BOX(vbox), _text_speed, FALSE, TRUE, 0);
+
+    _text_alt = gtk_label_new(" --- ");
+    gtk_widget_set_size_request(GTK_WIDGET(_text_alt), -1, 30);
+    gtk_box_pack_start(GTK_BOX(vbox), _text_alt, FALSE, TRUE, 0);
+
+    label = gtk_label_new(" ");
+    gtk_widget_set_size_request(GTK_WIDGET(label), -1, 10);
+    gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 0);
+
+    _sat_panel = gtk_drawing_area_new ();
+    gtk_widget_set_size_request (_sat_panel, -1, 100);
+    gtk_box_pack_start(GTK_BOX(vbox), _sat_panel, TRUE, TRUE, 0);
+
+    label = gtk_label_new(" ");
+    gtk_widget_set_size_request(GTK_WIDGET(label), -1, 10);
+    gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 0);
+
+    _text_time = gtk_label_new("--:--:--");
+    gtk_widget_set_size_request(GTK_WIDGET(_text_time), -1, 30);
+    gtk_box_pack_start(GTK_BOX(vbox), _text_time, FALSE, TRUE, 0);
+
+    _heading_panel = gtk_drawing_area_new ();
+    gtk_widget_set_size_request (_heading_panel, -1, 100);
+    gtk_box_pack_start(GTK_BOX(vbox), _heading_panel, TRUE, TRUE, 0);
+
+    _map_widget = gtk_drawing_area_new();
+
+    gtk_box_pack_start(GTK_BOX(hbox), _map_widget, TRUE, TRUE, 0);
+
+    gtk_widget_show_all(hbox);
+    gps_show_info(); /* hides info, if necessary. */
+
+    gtk_widget_realize(_map_widget);
+
+    /* Tweak the foreground and background colors a little bit... */
+    {
+        GdkColor color;
+        GdkGCValues values;
+        GdkColormap *colormap = gtk_widget_get_colormap(_map_widget);
+
+        gdk_gc_get_values(
+                _map_widget->style->fg_gc[GTK_STATE_NORMAL],
+                &values);
+        gdk_colormap_query_color(colormap, values.foreground.pixel, &color);
+        gtk_widget_modify_fg(_map_widget, GTK_STATE_ACTIVE, &color);
+
+        gdk_gc_get_values(
+                _map_widget->style->bg_gc[GTK_STATE_NORMAL],
+                &values);
+        gdk_colormap_query_color(colormap, values.foreground.pixel, &color);
+        gtk_widget_modify_bg(_map_widget, GTK_STATE_ACTIVE, &color);
+
+        /* Use a black background for _map_widget, since missing tiles are
+         * also drawn with a black background. */
+        color.red = 0; color.green = 0; color.blue = 0;
+        gtk_widget_modify_bg(_map_widget,
+                GTK_STATE_NORMAL, &color);
+    }
+
+    _map_pixmap = gdk_pixmap_new(_map_widget->window, 1, 1, -1);
+    /* -1: use bit depth of widget->window. */
+
+    _map_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, 1, 1);
+
+    _mut_exists_table = g_hash_table_new(
+            (GHashFunc)mut_exists_hashfunc, (GEqualFunc)mut_exists_equalfunc);
+    _mut_priority_tree = g_tree_new((GCompareFunc)mut_priority_comparefunc);
+
+    _mut_thread_pool = g_thread_pool_new(
+            (GFunc)thread_proc_mut, NULL, NUM_DOWNLOAD_THREADS, FALSE, NULL);
+    _mrt_thread_pool = g_thread_pool_new(
+            (GFunc)thread_render_map, NULL, 1, FALSE, NULL);
+
+    /* Connect signals. */
+    g_signal_connect(G_OBJECT(_window), "destroy",
+            G_CALLBACK(gtk_main_quit), NULL);
+
+    /* Initialize data. */
+
+    memset(&_autoroute_data, 0, sizeof(_autoroute_data));
+
+    latlon2unit(_gps.lat, _gps.lon, _pos.unitx, _pos.unity);
+
+    /* Initialize our line styles. */
+    update_gcs();
+
+    menu_init();
+    cmenu_init();
+    path_init();
+    gps_init();
+    input_init();
+    poi_db_connect();
+    display_init();
+
+    /* If present, attempt to load the file specified on the command line. */
+    if(argc > 1)
+    {
+        GnomeVFSResult vfs_result;
+        gint size;
+        gchar *buffer;
+        gchar *file_uri;
+
+        /* Get the selected filename. */
+        file_uri = gnome_vfs_make_uri_from_shell_arg(argv[1]);
+
+        if(GNOME_VFS_OK != (vfs_result = gnome_vfs_read_entire_file(
+                        file_uri, &size, &buffer)))
+        {
+            gchar buffer[BUFFER_SIZE];
+            snprintf(buffer, sizeof(buffer),
+                    "%s:\n%s", _("Failed to open file for reading"),
+                    gnome_vfs_result_to_string(vfs_result));
+            popup_error(_window, buffer);
+        }
+        else
+        {
+            if(gpx_path_parse(&_route, buffer, size, 0))
+            {
+                path_save_route_to_db();
+                MACRO_BANNER_SHOW_INFO(_window, _("Route Opened"));
+            }
+            else
+                popup_error(_window, _("Error parsing GPX file."));
+            g_free(buffer);
+        }
+        g_free(file_uri);
+    }
+
+    /* If we have a route, calculate the next point. */
+    route_find_nearest_point();
+
+    _conic_conn = con_ic_connection_new();
+    g_object_set(_conic_conn, "automatic-connection-events", TRUE, NULL);
+    g_signal_connect(G_OBJECT(_conic_conn), "connection-event",
+            G_CALLBACK(conic_conn_event), NULL);
+
+    g_idle_add((GSourceFunc)window_present, NULL);
+
+
+    osso_hw_set_event_cb(_osso, NULL, osso_cb_hw_state, NULL);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+static gint
+dbus_cb_default(const gchar *interface, const gchar *method,
+        GArray *arguments, gpointer data, osso_rpc_t *retval)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(!strcmp(method, "top_application"))
+        g_idle_add((GSourceFunc)window_present, NULL);
+
+    retval->type = DBUS_TYPE_INVALID;
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+    return OSSO_OK;
+}
+
+static gboolean
+osso_cb_hw_state_idle(osso_hw_state_t *state)
+{
+    static gboolean _must_save_data = FALSE;
+    printf("%s(inact=%d, save=%d, shut=%d, memlow=%d, state=%d)\n",
+            __PRETTY_FUNCTION__, state->system_inactivity_ind,
+            state->save_unsaved_data_ind, state->shutdown_ind,
+            state->memory_low_ind, state->sig_device_mode_ind);
+
+    if(state->save_unsaved_data_ind)
+    {
+        settings_save();
+        _must_save_data = TRUE;
+    }
+    else if(state->shutdown_ind)
+    {
+        maemo_mapper_destroy();
+        exit(1);
+    }
+    else if(state->memory_low_ind)
+    {
+        /* Try to reduce downloads by limiting the download threads.
+         * Note that we never reverse this, so it stays in effect until
+         * application restart. */
+        g_thread_pool_set_max_threads(_mut_thread_pool, 1, NULL);
+        g_thread_pool_set_max_threads(_mrt_thread_pool, 1, NULL);
+    }
+
+    g_free(state);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+    return FALSE;
+}
+
+static void
+osso_cb_hw_state(osso_hw_state_t *state, gpointer data)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+    osso_hw_state_t *state_copy = g_new(osso_hw_state_t, 1);
+    memcpy(state_copy, state, sizeof(osso_hw_state_t));
+    g_idle_add((GSourceFunc)osso_cb_hw_state_idle, state_copy);
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+gint
+main(gint argc, gchar *argv[])
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    /* Initialize localization. */
+    setlocale(LC_ALL, "");
+    bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
+    bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
+    textdomain(GETTEXT_PACKAGE);
+
+    g_thread_init(NULL);
+
+    /* Initialize _osso. */
+    _osso = osso_initialize("com.gnuite.maemo_mapper", VERSION, TRUE, NULL);
+    if(!_osso)
+    {
+        g_printerr("osso_initialize failed.\n");
+        return 1;
+    }
+
+    gtk_init(&argc, &argv);
+
+    /* Init gconf. */
+    g_type_init();
+    gconf_init(argc, argv, NULL);
+
+    /* Init Gnome-VFS. */
+    gnome_vfs_init();
+
+    maemo_mapper_init(argc, argv);
+
+    if(OSSO_OK != osso_rpc_set_default_cb_f(_osso, dbus_cb_default, NULL))
+    {
+        g_printerr("osso_rpc_set_default_cb_f failed.\n");
+        return 1;
+    }
+
+    gtk_main();
+
+    maemo_mapper_destroy();
+
+    osso_deinitialize(_osso);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+    exit(0);
+}
+
diff --git a/src/main.h b/src/main.h
new file mode 100644 (file)
index 0000000..a401b9d
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAEMO_MAPPER_MAIN_H
+#define MAEMO_MAPPER_MAIN_H
+
+gint main(gint argc, gchar *argv[]);
+
+void conic_recommend_connected();
+void conic_ensure_connected();
+
+#endif /* ifndef MAEMO_MAPPER_MAIN_H */
diff --git a/src/maps.c b/src/maps.c
new file mode 100644 (file)
index 0000000..309b4b8
--- /dev/null
@@ -0,0 +1,2366 @@
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#define _GNU_SOURCE
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <glib/gstdio.h>
+#include <fcntl.h>
+#include <osso-helplib.h>
+#include <hildon-widgets/hildon-note.h>
+#include <hildon-widgets/hildon-file-chooser-dialog.h>
+#include <hildon-widgets/hildon-number-editor.h>
+#include <hildon-widgets/hildon-banner.h>
+#include <hildon-widgets/hildon-input-mode-hint.h>
+
+#include <locale.h>
+
+#include "types.h"
+#include "data.h"
+#include "defines.h"
+
+#include "display.h"
+#include "main.h"
+#include "maps.h"
+#include "menu.h"
+#include "settings.h"
+#include "util.h"
+
+
+gboolean
+mapdb_exists(RepoData *repo, gint zoom, gint tilex, gint tiley,
+        gboolean should_lock)
+{
+    gboolean exists;
+    vprintf("%s(%s, %d, %d, %d)\n", __PRETTY_FUNCTION__,
+            repo->name, zoom, tilex, tiley);
+
+    if(should_lock)
+        g_mutex_lock(_mapdb_mutex);
+
+    if(!repo->db)
+    {
+        /* There is no cache.  Return FALSE. */
+        if(should_lock)
+            g_mutex_unlock(_mapdb_mutex);
+        vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+        return FALSE;
+    }
+
+#ifdef MAPDB_SQLITE
+    /* Attempt to retrieve map from database. */
+    if(SQLITE_OK == sqlite3_bind_int(repo->stmt_map_exists, 1, zoom)
+    && SQLITE_OK == sqlite3_bind_int(repo->stmt_map_exists, 2, tilex)
+    && SQLITE_OK == sqlite3_bind_int(repo->stmt_map_exists, 3, tiley)
+    && SQLITE_ROW == sqlite3_step(repo->stmt_map_exists)
+    && sqlite3_column_int(repo->stmt_map_exists, 0) > 0)
+    {
+        exists = TRUE;
+    }
+    else
+    {
+        exists = FALSE;
+    }
+    sqlite3_reset(repo->stmt_map_exists);
+#else
+    {
+        datum d;
+        gint key[] = {
+            GLONG_TO_BE(zoom),
+            GLONG_TO_BE(tilex),
+            GLONG_TO_BE(tiley)
+        };
+        d.dptr = (gchar*)&key;
+        d.dsize = sizeof(key);
+        exists = gdbm_exists(repo->db, d);
+    }
+#endif
+
+    if(should_lock)
+        g_mutex_unlock(_mapdb_mutex);
+
+    vprintf("%s(): return %d\n", __PRETTY_FUNCTION__, exists);
+    return exists;
+}
+
+GdkPixbuf*
+mapdb_get(RepoData *repo, gint zoom, gint tilex, gint tiley)
+{
+    GdkPixbuf *pixbuf = NULL;
+    vprintf("%s(%s, %d, %d, %d)\n", __PRETTY_FUNCTION__,
+            repo->name, zoom, tilex, tiley);
+
+    /* Grab the mapdb lock so that we have temporary exclusive access.  This
+     * makes the draw refresh a little bit faster. */
+    g_mutex_lock(_mapdb_mutex);
+
+    if(!repo->db)
+    {
+        /* There is no cache.  Return NULL. */
+        g_mutex_unlock(_mapdb_mutex);
+        vprintf("%s(): return NULL\n", __PRETTY_FUNCTION__);
+        return NULL;
+    }
+
+#ifdef MAPDB_SQLITE
+    /* Attempt to retrieve map from database. */
+    if(SQLITE_OK == sqlite3_bind_int(repo->stmt_map_select, 1, zoom)
+    && SQLITE_OK == sqlite3_bind_int(repo->stmt_map_select, 2, tilex)
+    && SQLITE_OK == sqlite3_bind_int(repo->stmt_map_select, 3, tiley)
+    && SQLITE_ROW == sqlite3_step(repo->stmt_map_select))
+    {
+        const gchar *bytes = NULL;
+        gint size = sqlite3_column_bytes(repo->stmt_map_select, 0);
+
+        /* "Pixbufs" of size less than or equal to MAX_PIXBUF_DUP_SIZE are
+         * actually keys into the dups table. */
+        if(size <= MAX_PIXBUF_DUP_SIZE)
+        {
+            gint hash = sqlite3_column_int(repo->stmt_map_select, 0);
+            if(SQLITE_OK == sqlite3_bind_int(repo->stmt_dup_select, 1, hash)
+            && SQLITE_ROW == sqlite3_step(repo->stmt_dup_select))
+            {
+                bytes = sqlite3_column_blob(repo->stmt_dup_select, 0);
+                size = sqlite3_column_bytes(repo->stmt_dup_select, 0);
+            }
+            else
+            {
+                /* Not there?  Delete the entry, then. */
+                if(SQLITE_OK != sqlite3_bind_int(
+                            repo->stmt_map_delete, 1, zoom)
+                || SQLITE_OK != sqlite3_bind_int(
+                    repo->stmt_map_delete, 2, tilex)
+                || SQLITE_OK != sqlite3_bind_int(
+                    repo->stmt_map_delete, 3, tiley)
+                || SQLITE_DONE != sqlite3_step(repo->stmt_map_delete))
+                {
+                    printf("Error in stmt_map_delete: %s\n", 
+                                sqlite3_errmsg(repo->db));
+                }
+                sqlite3_reset(repo->stmt_map_delete);
+
+                /* We have no bytes to return to the caller. */
+                bytes = NULL;
+            }
+            /* Don't reset the statement yet - we need the blob. */
+        }
+        else
+        {
+            bytes = sqlite3_column_blob(repo->stmt_map_select, 0);
+        }
+        if(bytes)
+        {
+            GError *error = NULL;
+            GdkPixbufLoader *loader = gdk_pixbuf_loader_new();
+            gdk_pixbuf_loader_write(loader, bytes, size, NULL);
+            gdk_pixbuf_loader_close(loader, &error);
+            if(!error)
+                pixbuf = g_object_ref(gdk_pixbuf_loader_get_pixbuf(loader));
+            g_object_unref(loader);
+        }
+        if(size <= MAX_PIXBUF_DUP_SIZE)
+            sqlite3_reset(repo->stmt_dup_select);
+    }
+    sqlite3_reset(repo->stmt_map_select);
+#else
+    {
+        datum d;
+        gint key[] = {
+            GLONG_TO_BE(zoom),
+            GLONG_TO_BE(tilex),
+            GLONG_TO_BE(tiley)
+        };
+        d.dptr = (gchar*)&key;
+        d.dsize = sizeof(key);
+        d = gdbm_fetch(repo->db, d);
+        if(d.dptr)
+        {
+            GError *error = NULL;
+            GdkPixbufLoader *loader = gdk_pixbuf_loader_new();
+            gdk_pixbuf_loader_write(loader, d.dptr, d.dsize, NULL);
+            g_free(d.dptr);
+            gdk_pixbuf_loader_close(loader, &error);
+            if(!error)
+                pixbuf = g_object_ref(gdk_pixbuf_loader_get_pixbuf(loader));
+            g_object_unref(loader);
+        }
+    }
+#endif
+
+    g_mutex_unlock(_mapdb_mutex);
+
+    vprintf("%s(): return %p\n", __PRETTY_FUNCTION__, pixbuf);
+    return pixbuf;
+}
+
+#ifdef MAPDB_SQLITE
+static gboolean
+mapdb_checkdec(RepoData *repo, gint zoom, gint tilex, gint tiley)
+{
+    gboolean success = TRUE;
+    vprintf("%s(%s, %d, %d, %d)\n", __PRETTY_FUNCTION__,
+            repo->name, zoom, tilex, tiley);
+
+    /* First, we have to check if the old map was a dup. */
+    if(SQLITE_OK == sqlite3_bind_int(repo->stmt_map_select, 1, zoom)
+    && SQLITE_OK == sqlite3_bind_int(repo->stmt_map_select, 2, tilex)
+    && SQLITE_OK == sqlite3_bind_int(repo->stmt_map_select, 3, tiley)
+    && SQLITE_ROW == sqlite3_step(repo->stmt_map_select)
+    && sqlite3_column_bytes(repo->stmt_map_select, 0)
+            <= MAX_PIXBUF_DUP_SIZE)
+    {
+        /* Old map was indeed a dup. Decrement the reference count. */
+        gint hash = sqlite3_column_int(repo->stmt_map_select, 0);
+        if(SQLITE_OK != sqlite3_bind_int(
+                    repo->stmt_dup_decrem, 1, hash)
+        || SQLITE_DONE != sqlite3_step(repo->stmt_dup_decrem)
+        || SQLITE_OK != sqlite3_bind_int(
+                    repo->stmt_dup_delete, 1, hash)
+        || SQLITE_DONE != sqlite3_step(repo->stmt_dup_delete))
+        {
+            success = FALSE;
+            printf("Error in stmt_dup_decrem: %s\n",
+                    sqlite3_errmsg(repo->db));
+        }
+        sqlite3_reset(repo->stmt_dup_delete);
+        sqlite3_reset(repo->stmt_dup_decrem);
+    }
+    sqlite3_reset(repo->stmt_map_select);
+
+    vprintf("%s(): return %d\n", __PRETTY_FUNCTION__, success);
+    return success;
+}
+#endif
+
+static gboolean
+mapdb_update(gboolean exists, RepoData *repo,
+        gint zoom, gint tilex, gint tiley, void *bytes, gint size)
+{
+#ifdef MAPDB_SQLITE
+    sqlite3_stmt *stmt;
+    gint hash = 0;
+#endif
+    gint success = TRUE;
+    vprintf("%s(%s, %d, %d, %d)\n", __PRETTY_FUNCTION__,
+            repo->name, zoom, tilex, tiley);
+
+    g_mutex_lock(_mapdb_mutex);
+
+    if(!repo->db)
+    {
+        /* There is no cache.  Return FALSE. */
+        g_mutex_unlock(_mapdb_mutex);
+        vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+        return FALSE;
+    }
+
+#ifdef MAPDB_SQLITE
+    /* At least try to open a transaction. */
+    sqlite3_step(repo->stmt_trans_begin);
+    sqlite3_reset(repo->stmt_trans_begin);
+
+    /* Pixbufs of size MAX_PIXBUF_DUP_SIZE or less are special.  They are
+     * probably PNGs of a single color (like blue for water or beige for empty
+     * land).  To reduce redundancy in the database, we will store them in a
+     * separate table and, in the maps table, only refer to them. */
+    if(size <= MAX_PIXBUF_DUP_SIZE)
+    {
+        /* Duplicate pixbuf. */
+        if(exists)
+        {
+            /* First, check if we need to remove a count from the dups table.*/
+            mapdb_checkdec(repo, zoom, tilex, tiley);
+        }
+        if(success)
+        {
+            /* Compute hash of the bytes. */
+            gchar *cur = bytes, *end = bytes + size;
+            hash = *cur;
+            while(cur < end)
+                hash = (hash << 5) - hash + *(++cur);
+
+            /* Check if dup already exists. */
+            if(SQLITE_OK == sqlite3_bind_int(repo->stmt_dup_exists, 1, hash)
+            && SQLITE_ROW == sqlite3_step(repo->stmt_dup_exists)
+            && sqlite3_column_int(repo->stmt_dup_exists, 0) > 0)
+            {
+                /* Dup already exists - increment existing entry. */
+                if(SQLITE_OK != sqlite3_bind_int(repo->stmt_dup_increm,1, hash)
+                || SQLITE_DONE != sqlite3_step(repo->stmt_dup_increm))
+                {
+                    success = FALSE;
+                    printf("Error in stmt_dup_increm: %s\n",
+                            sqlite3_errmsg(repo->db));
+                }
+                sqlite3_reset(repo->stmt_dup_increm);
+            }
+            else
+            {
+                /* Dup doesn't exist - add new entry. */
+                if(SQLITE_OK != sqlite3_bind_int(repo->stmt_dup_insert,1, hash)
+                || SQLITE_OK != sqlite3_bind_blob(repo->stmt_dup_insert,
+                    2, bytes, size, NULL)
+                || SQLITE_DONE != sqlite3_step(repo->stmt_dup_insert))
+                {
+                    success = FALSE;
+                    printf("Error in stmt_dup_insert: %s\n",
+                            sqlite3_errmsg(repo->db));
+                }
+                sqlite3_reset(repo->stmt_dup_insert);
+            }
+            sqlite3_reset(repo->stmt_dup_exists);
+        }
+        /* Now, if successful so far, we fall through the end of this if
+         * statement and insert the hash as the blob.  Setting bytes to NULL
+         * is the signal to do this. */
+        bytes = NULL;
+    }
+
+    if(success)
+    {
+        stmt = exists ? repo->stmt_map_update : repo->stmt_map_insert;
+
+        /* Attempt to insert map from database. */
+        if(SQLITE_OK != (bytes ? sqlite3_bind_blob(stmt, 1, bytes, size, NULL)
+                    : sqlite3_bind_int(stmt, 1, hash))
+        || SQLITE_OK != sqlite3_bind_int(stmt, 2, zoom)
+        || SQLITE_OK != sqlite3_bind_int(stmt, 3, tilex)
+        || SQLITE_OK != sqlite3_bind_int(stmt, 4, tiley)
+        || SQLITE_DONE != sqlite3_step(stmt))
+        {
+            success = FALSE;
+            printf("Error in mapdb_update: %s\n", sqlite3_errmsg(repo->db));
+        }
+        sqlite3_reset(stmt);
+    }
+
+    if(success)
+    {
+        sqlite3_step(repo->stmt_trans_commit);
+        sqlite3_reset(repo->stmt_trans_commit);
+    }
+    else
+    {
+        sqlite3_step(repo->stmt_trans_rollback);
+        sqlite3_reset(repo->stmt_trans_rollback);
+    }
+
+#else
+    {
+        datum dkey, dcon;
+        gint key[] = {
+            GLONG_TO_BE(zoom),
+            GLONG_TO_BE(tilex),
+            GLONG_TO_BE(tiley)
+        };
+        dkey.dptr = (gchar*)&key;
+        dkey.dsize = sizeof(key);
+        dcon.dptr = bytes;
+        dcon.dsize = size;
+        success = !gdbm_store(repo->db, dkey, dcon, GDBM_REPLACE);
+    }
+#endif
+    g_mutex_unlock(_mapdb_mutex);
+
+    vprintf("%s(): return %d\n", __PRETTY_FUNCTION__, success);
+    return success;
+}
+
+static gboolean
+mapdb_delete(RepoData *repo, gint zoom, gint tilex, gint tiley)
+{
+    gint success = FALSE;
+    vprintf("%s(%s, %d, %d, %d)\n", __PRETTY_FUNCTION__,
+            repo->name, zoom, tilex, tiley);
+
+    g_mutex_lock(_mapdb_mutex);
+
+    if(!repo->db)
+    {
+        /* There is no cache.  Return FALSE. */
+        g_mutex_unlock(_mapdb_mutex);
+        vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+        return FALSE;
+    }
+
+#ifdef MAPDB_SQLITE
+    /* At least try to open a transaction. */
+    sqlite3_step(repo->stmt_trans_begin);
+    sqlite3_reset(repo->stmt_trans_begin);
+
+    /* First, check if we need to remove a count from the dups table. */
+    /* Then, attempt to delete map from database. */
+    if(!mapdb_checkdec(repo, zoom, tilex, tiley)
+    || SQLITE_OK != sqlite3_bind_int(repo->stmt_map_delete, 1, zoom)
+    || SQLITE_OK != sqlite3_bind_int(repo->stmt_map_delete, 2, tilex)
+    || SQLITE_OK != sqlite3_bind_int(repo->stmt_map_delete, 3, tiley)
+    || SQLITE_DONE != sqlite3_step(repo->stmt_map_delete))
+    {
+        success = FALSE;
+        printf("Error in stmt_map_delete: %s\n", 
+                    sqlite3_errmsg(repo->db));
+    }
+    sqlite3_reset(repo->stmt_map_delete);
+
+    if(success)
+    {
+        sqlite3_step(repo->stmt_trans_commit);
+        sqlite3_reset(repo->stmt_trans_commit);
+    }
+    else
+    {
+        sqlite3_step(repo->stmt_trans_rollback);
+        sqlite3_reset(repo->stmt_trans_rollback);
+    }
+#else
+    {
+        datum d;
+        gint key[] = {
+            GLONG_TO_BE(zoom),
+            GLONG_TO_BE(tilex),
+            GLONG_TO_BE(tiley)
+        };
+        d.dptr = (gchar*)&key;
+        d.dsize = sizeof(key);
+        success = !gdbm_delete(repo->db, d);
+    }
+#endif
+    g_mutex_unlock(_mapdb_mutex);
+
+    vprintf("%s(): return %d\n", __PRETTY_FUNCTION__, success);
+    return success;
+}
+
+void
+set_repo_type(RepoData *repo)
+{
+    printf("%s(%s)\n", __PRETTY_FUNCTION__, repo->url);
+
+    if(repo->url && *repo->url)
+    {
+        gchar *url = g_utf8_strdown(repo->url, -1);
+
+        /* Determine type of repository. */
+        if(strstr(url, "service=wms"))
+            repo->type = REPOTYPE_WMS;
+        else if(strstr(url, "%s"))
+            repo->type = REPOTYPE_QUAD_QRST;
+        else if(strstr(url, "%0d"))
+            repo->type = REPOTYPE_XYZ_INV;
+        else if(strstr(url, "%0s"))
+            repo->type = REPOTYPE_QUAD_ZERO;
+        else
+            repo->type = REPOTYPE_XYZ;
+
+        g_free(url);
+    }
+    else
+        repo->type = REPOTYPE_NONE;
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+/* Returns the directory containing the given database filename, or NULL
+ * if the database file could not be created. */
+static gboolean
+repo_make_db(RepoData *rd)
+{
+    printf("%s(%s)\n", __PRETTY_FUNCTION__, rd->db_filename);
+    gchar *db_dirname;
+    gint fd;
+
+    db_dirname = g_path_get_dirname(rd->db_filename);
+    
+    /* Check if db_filename is a directory and ask to upgrade. */
+    if(g_file_test(rd->db_filename, G_FILE_TEST_IS_DIR))
+    {
+        gchar buffer[BUFFER_SIZE];
+        gchar *new_name = g_strdup_printf("%s.db", rd->db_filename);
+        g_free(rd->db_filename);
+        rd->db_filename = new_name;
+
+        snprintf(buffer, sizeof(buffer), "%s",
+                _("The current repository is in a legacy format and will "
+                    "be converted.  You should delete your old maps if you "
+                    "no longer plan to use them."));
+        popup_error(_window, buffer);
+    }
+
+    if(g_mkdir_with_parents(db_dirname, 0755))
+    {
+        g_free(db_dirname);
+        return FALSE;
+    }
+    g_free(db_dirname);
+
+    if(!g_file_test(rd->db_filename, G_FILE_TEST_EXISTS))
+    {
+        fd = g_creat(rd->db_filename, 0644);
+        if(fd == -1)
+        {
+            g_free(db_dirname);
+            return FALSE;
+        }
+        close(fd);
+    }
+
+    vprintf("%s(): return %d\n", __PRETTY_FUNCTION__,
+           g_file_test(rd->db_filename, G_FILE_TEST_EXISTS));
+    return g_file_test(rd->db_filename, G_FILE_TEST_EXISTS);
+}
+
+gboolean
+repo_set_curr(RepoData *rd)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+    if(!rd->db_filename || !*rd->db_filename
+            || repo_make_db(rd))
+    {
+        if(_curr_repo)
+        {
+            if(_curr_repo->db)
+            {
+                g_mutex_lock(_mapdb_mutex);
+#ifdef MAPDB_SQLITE
+                sqlite3_close(_curr_repo->db);
+#else
+                gdbm_close(_curr_repo->db);
+#endif
+                _curr_repo->db = NULL;
+                g_mutex_unlock(_mapdb_mutex);
+            }
+        }
+
+        /* Set the current repository! */
+        _curr_repo = rd;
+
+        /* Set up the database. */
+        if(_curr_repo->db_filename && *_curr_repo->db_filename)
+        {
+
+#ifdef MAPDB_SQLITE
+            if(SQLITE_OK != (sqlite3_open(_curr_repo->db_filename,
+                            &(_curr_repo->db)))
+            /* Open worked. Now create tables, failing if they already exist.*/
+            || (sqlite3_exec(_curr_repo->db,
+                        "create table maps ("
+                        "zoom integer, "
+                        "tilex integer, "
+                        "tiley integer, "
+                        "pixbuf blob, "
+                        "primary key (zoom, tilex, tiley))"
+                        ";"
+                        "create table dups ("
+                        "hash integer primary key, "
+                        "uses integer, "
+                        "pixbuf blob)",
+                        NULL, NULL, NULL), FALSE) /* !! Comma operator !! */
+                /* Prepare select map statement. */
+             || SQLITE_OK != sqlite3_prepare(_curr_repo->db,
+                        "select pixbuf from maps "
+                        "where zoom = ? and tilex = ? and tiley = ?",
+                        -1, &_curr_repo->stmt_map_select, NULL)
+                /* Prepare exists map statement. */
+             || SQLITE_OK != sqlite3_prepare(_curr_repo->db,
+                        "select count(*) from maps "
+                        "where zoom = ? and tilex = ? and tiley = ?",
+                        -1, &_curr_repo->stmt_map_exists, NULL)
+                /* Prepare insert map statement. */
+             || SQLITE_OK != sqlite3_prepare(_curr_repo->db,
+                        "insert into maps (pixbuf, zoom, tilex, tiley)"
+                        " values (?, ?, ?, ?)",
+                        -1, &_curr_repo->stmt_map_insert, NULL)
+                /* Prepare update map statement. */
+             || SQLITE_OK != sqlite3_prepare(_curr_repo->db,
+                        "update maps set pixbuf = ? "
+                        "where zoom = ? and tilex = ? and tiley = ?",
+                        -1, &_curr_repo->stmt_map_update, NULL)
+                /* Prepare delete map statement. */
+             || SQLITE_OK != sqlite3_prepare(_curr_repo->db,
+                        "delete from maps "
+                        "where zoom = ? and tilex = ? and tiley = ?",
+                        -1, &_curr_repo->stmt_map_delete, NULL)
+
+                /* Prepare select-by-map dup statement. */
+                /* Prepare select-by-hash dup statement. */
+             || SQLITE_OK != sqlite3_prepare(_curr_repo->db,
+                        "select pixbuf from dups "
+                        "where hash = ?",
+                        -1, &_curr_repo->stmt_dup_select, NULL)
+                /* Prepare exists map statement. */
+             || SQLITE_OK != sqlite3_prepare(_curr_repo->db,
+                        "select count(*) from dups "
+                        "where hash = ?",
+                        -1, &_curr_repo->stmt_dup_exists, NULL)
+                /* Prepare insert dup statement. */
+             || SQLITE_OK != sqlite3_prepare(_curr_repo->db,
+                        "insert into dups (hash, pixbuf, uses) "
+                        "values (?, ?, 1)",
+                        -1, &_curr_repo->stmt_dup_insert, NULL)
+                /* Prepare increment dup statement. */
+             || SQLITE_OK != sqlite3_prepare(_curr_repo->db,
+                        "update dups "
+                        "set uses = uses + 1 "
+                        "where hash = ?",
+                        -1, &_curr_repo->stmt_dup_increm, NULL)
+                /* Prepare decrement dup statement. */
+             || SQLITE_OK != sqlite3_prepare(_curr_repo->db,
+                        "update dups "
+                        "set uses = uses - 1 "
+                        "where hash = ? ",
+                        -1, &_curr_repo->stmt_dup_decrem, NULL)
+                /* Prepare delete dup statement. */
+             || SQLITE_OK != sqlite3_prepare(_curr_repo->db,
+                        "delete from dups "
+                        "where hash = ? and uses <= 0",
+                        -1, &_curr_repo->stmt_dup_delete, NULL)
+
+                /* Prepare begin-transaction statement. */
+             || SQLITE_OK != sqlite3_prepare(_curr_repo->db,
+                     "begin transaction",
+                        -1, &_curr_repo->stmt_trans_begin, NULL)
+             || SQLITE_OK != sqlite3_prepare(_curr_repo->db,
+                     "commit transaction",
+                        -1, &_curr_repo->stmt_trans_commit, NULL)
+             || SQLITE_OK != sqlite3_prepare(_curr_repo->db,
+                     "rollback transaction", -1,
+                     &_curr_repo->stmt_trans_rollback, NULL))
+            {
+                gchar buffer[BUFFER_SIZE];
+                snprintf(buffer, sizeof(buffer), "%s: %s\n%s",
+                        _("Failed to open map database for repository"),
+                        sqlite3_errmsg(_curr_repo->db),
+                        _("Downloaded maps will not be cached."));
+                sqlite3_close(_curr_repo->db);
+                _curr_repo->db = NULL;
+                popup_error(_window, buffer);
+            }
+#else
+            _curr_repo->db = gdbm_open(_curr_repo->db_filename,
+                    0, GDBM_WRCREAT, 0644, NULL);
+            if(!_curr_repo->db)
+            {
+                gchar buffer[BUFFER_SIZE];
+                snprintf(buffer, sizeof(buffer), "%s\n%s",
+                        _("Failed to open map database for repository"),
+                        _("Downloaded maps will not be cached."));
+                _curr_repo->db = NULL;
+                popup_error(_window, buffer);
+            }
+#endif
+        }
+        else
+        {
+            _curr_repo->db = NULL;
+        }
+        vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+        return TRUE;
+    }
+    else
+    {
+        gchar buffer[BUFFER_SIZE];
+        snprintf(buffer, sizeof(buffer), "%s: %s",
+                _("Unable to create map database for repository"), rd->name);
+        popup_error(_window, buffer);
+        _curr_repo = rd;
+        vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+        return FALSE;
+    }
+}
+
+/**
+ * Given a wms uri pattern, compute the coordinate transformation and
+ * trimming.
+ * 'proj' is used for the conversion
+ */
+static gchar*
+map_convert_wms_to_wms(gint tilex, gint tiley, gint zoomlevel, gchar* uri)
+{
+    gint system_retcode;
+    gchar cmd[BUFFER_SIZE], srs[BUFFER_SIZE];
+    gchar *ret = NULL;
+    FILE* in;
+    gfloat lon1, lat1, lon2, lat2;
+
+    gchar *widthstr   = strcasestr(uri,"WIDTH=");
+    gchar *heightstr  = strcasestr(uri,"HEIGHT=");
+    gchar *srsstr     = strcasestr(uri,"SRS=EPSG");
+    gchar *srsstre    = strchr(srsstr,'&');
+    vprintf("%s()\n", __PRETTY_FUNCTION__);
+
+    /* missing: test if found */
+    strcpy(srs,"epsg");
+    strncpy(srs+4,srsstr+8,256);
+    /* missing: test srsstre-srsstr < 526 */
+    srs[srsstre-srsstr-4] = 0;
+    /* convert to lower, as WMC is EPSG and cs2cs is epsg */
+
+    gint dwidth  = widthstr ? atoi(widthstr+6) - TILE_SIZE_PIXELS : 0;
+    gint dheight = heightstr ? atoi(heightstr+7) - TILE_SIZE_PIXELS : 0;
+
+    unit2latlon(tile2zunit(tilex,zoomlevel)
+            - pixel2zunit(dwidth/2,zoomlevel),
+            tile2zunit(tiley+1,zoomlevel)
+            + pixel2zunit((dheight+1)/2,zoomlevel),
+            lat1, lon1);
+
+    unit2latlon(tile2zunit(tilex+1,zoomlevel)
+            + pixel2zunit((dwidth+1)/2,zoomlevel),
+            tile2zunit(tiley,zoomlevel)
+            - pixel2zunit(dheight/2,zoomlevel),
+            lat2, lon2);
+
+    setlocale(LC_NUMERIC, "C");
+
+    snprintf(cmd, sizeof(cmd),
+            "(echo \"%.6f %.6f\"; echo \"%.6f %.6f\") | "
+            "/usr/bin/cs2cs +proj=longlat +datum=WGS84 +to +init=%s -f %%.6f "
+            " > /tmp/tmpcs2cs ",
+            lon1, lat1, lon2, lat2, srs);
+    vprintf("Running command: %s\n", cmd);
+    system_retcode = system(cmd);
+
+    if(system_retcode)
+        g_printerr("cs2cs returned error code %d\n",
+                WEXITSTATUS(system_retcode));
+    else if(!(in = g_fopen("/tmp/tmpcs2cs","r")))
+        g_printerr("Cannot open results of conversion\n");
+    else if(5 != fscanf(in,"%f %f %s %f %f", &lon1, &lat1, cmd, &lon2, &lat2))
+    {
+        g_printerr("Wrong conversion\n");
+        fclose(in);
+    }
+    else
+    {
+        fclose(in);
+        ret = g_strdup_printf(uri, lon1, lat1, lon2, lat2);
+    }
+
+    setlocale(LC_NUMERIC, "");
+
+    vprintf("%s(): return %s\n", __PRETTY_FUNCTION__, ret);
+    return ret;
+}
+
+
+/**
+ * Given the xyz coordinates of our map coordinate system, write the qrst
+ * quadtree coordinates to buffer.
+ */
+static void
+map_convert_coords_to_quadtree_string(gint x, gint y, gint zoomlevel,
+                                      gchar *buffer, const gchar initial,
+                                      const gchar *const quadrant)
+{
+    gchar *ptr = buffer;
+    gint n;
+    vprintf("%s()\n", __PRETTY_FUNCTION__);
+
+    if (initial)
+        *ptr++ = initial;
+
+    for(n = 16 - zoomlevel; n >= 0; n--)
+    {
+        gint xbit = (x >> n) & 1;
+        gint ybit = (y >> n) & 1;
+        *ptr++ = quadrant[xbit + 2 * ybit];
+    }
+    *ptr++ = '\0';
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+/**
+ * Construct the URL that we should fetch, based on the current URI format.
+ * This method works differently depending on if a "%s" string is present in
+ * the URI format, since that would indicate a quadtree-based map coordinate
+ * system.
+ */
+static gchar*
+map_construct_url(RepoData *repo, gint zoom, gint tilex, gint tiley)
+{
+    gchar *retval;
+    vprintf("%s()\n", __PRETTY_FUNCTION__);
+    switch(repo->type)
+    {
+        case REPOTYPE_XYZ:
+            retval = g_strdup_printf(repo->url, tilex, tiley, zoom);
+            break;
+
+        case REPOTYPE_XYZ_INV:
+            retval = g_strdup_printf(repo->url, 17 - zoom, tilex, tiley);
+            break;
+
+        case REPOTYPE_QUAD_QRST:
+        {
+            gchar location[MAX_ZOOM + 2];
+            map_convert_coords_to_quadtree_string(
+                    tilex, tiley, zoom, location, 't', "qrts");
+            retval = g_strdup_printf(repo->url, location);
+            break;
+        }
+
+        case REPOTYPE_QUAD_ZERO:
+        {
+            /* This is a zero-based quadtree URI. */
+            gchar location[MAX_ZOOM + 2];
+            map_convert_coords_to_quadtree_string(
+                    tilex, tiley, zoom, location, '\0', "0123");
+            retval = g_strdup_printf(repo->url, location);
+            break;
+        }
+
+        case REPOTYPE_WMS:
+            retval = map_convert_wms_to_wms(tilex, tiley, zoom, repo->url);
+            break;
+
+        default:
+            retval = g_strdup(repo->url);
+            break;
+    }
+    vprintf("%s(): return \"%s\"\n", __PRETTY_FUNCTION__, retval);
+    return retval;
+}
+
+static gboolean
+mapdb_initiate_update_banner_idle()
+{
+    if(!_download_banner && _num_downloads != _curr_download)
+        _download_banner = hildon_banner_show_progress(
+                _window, NULL, _("Processing Maps"));
+    return FALSE;
+}
+
+/**
+ * Initiate a download of the given xyz coordinates using the given buffer
+ * as the URL.  If the map already exists on disk, or if we are already
+ * downloading the map, then this method does nothing.
+ */
+gboolean
+mapdb_initiate_update(RepoData *repo, gint zoom, gint tilex, gint tiley,
+        gint update_type, gint batch_id, gint priority,
+        ThreadLatch *refresh_latch)
+{
+    MapUpdateTask *mut;
+    MapUpdateTask *old_mut;
+    gboolean is_replacing = FALSE;
+    static gint mut_id = INT_MIN;
+    vprintf("%s(%s, %d, %d, %d, %d)\n", __PRETTY_FUNCTION__,
+            repo->name, zoom, tilex, tiley, update_type);
+
+    mut = g_slice_new(MapUpdateTask);
+    mut->zoom = zoom;
+    mut->tilex = tilex;
+    mut->tiley = tiley;
+    mut->update_type = update_type;
+
+    g_mutex_lock(_mut_priority_mutex);
+    if(NULL != (old_mut = g_hash_table_lookup(_mut_exists_table, mut)))
+    {
+        /* Check if new mut is in a newer batch that the old mut. */
+        if(old_mut->batch_id < batch_id && old_mut->pending)
+        {
+            /* It is, so remove the old one so we can re-add this one. */
+            g_hash_table_remove(_mut_exists_table, old_mut);
+            g_tree_remove(_mut_priority_tree, old_mut);
+            g_slice_free(MapUpdateTask, old_mut);
+            is_replacing = TRUE;
+        }
+        else
+        {
+            /* It's not, so just ignore it. */
+            g_mutex_unlock(_mut_priority_mutex);
+            g_slice_free(MapUpdateTask, mut);
+            vprintf("%s(): return FALSE (1)\n", __PRETTY_FUNCTION__);
+            return FALSE;
+        }
+    }
+    g_hash_table_insert(_mut_exists_table, mut, mut);
+
+    mut->repo = repo;
+    mut->refresh_latch = refresh_latch;
+    mut->priority = priority;
+    mut->batch_id = batch_id;
+    mut->pending = TRUE;
+    mut->id = ++mut_id;
+    mut->pixbuf = NULL;
+    mut->vfs_result = GNOME_VFS_OK;
+
+    g_tree_insert(_mut_priority_tree, mut, mut);
+    g_mutex_unlock(_mut_priority_mutex);
+
+    if(!is_replacing)
+    {
+        /* Increment download count and (possibly) display banner. */
+        if(!_num_downloads++ && !_download_banner)
+            g_idle_add((GSourceFunc)mapdb_initiate_update_banner_idle, NULL);
+
+        g_thread_pool_push(_mut_thread_pool, (gpointer)1, NULL);
+    }
+
+    vprintf("%s(): return FALSE (2)\n", __PRETTY_FUNCTION__);
+    return FALSE;
+}
+
+static gboolean
+get_next_mut(gpointer key, gpointer value, MapUpdateTask **data)
+{
+    *data = key;
+    return TRUE;
+}
+
+gboolean
+thread_proc_mut()
+{
+    gint retries;
+    MapUpdateTask *mut = NULL;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    /* Wait until we are connected. */
+    conic_ensure_connected();
+
+    g_mutex_lock(_mut_priority_mutex);
+    g_tree_foreach(_mut_priority_tree, (GTraverseFunc)get_next_mut, &mut);
+    if(!mut)
+    {
+        printf("NOT SURE WHAT HAPPENED HERE.\n");
+        g_mutex_unlock(_mut_priority_mutex);
+        return FALSE;
+    }
+    mut->pending = FALSE;
+    g_tree_remove(_mut_priority_tree, mut);
+    g_mutex_unlock(_mut_priority_mutex);
+
+    printf("%s(%s, %d, %d, %d)\n", __PRETTY_FUNCTION__,
+            mut->repo->name, mut->zoom, mut->tilex, mut->tiley);
+
+    if(mut->repo != _curr_repo)
+    {
+        /* Do nothing. */
+    }
+    else if(mut->update_type == MAP_UPDATE_DELETE)
+    {
+        /* Easy - just delete the entry from the database.  We don't care about
+         * failures (sorry). */
+        if(mut->repo->db)
+            mapdb_delete(mut->repo, mut->zoom, mut->tilex, mut->tiley);
+    }
+    else
+    {
+        for(retries = INITIAL_DOWNLOAD_RETRIES; retries > 0; --retries)
+        {
+            gboolean exists = FALSE;
+            gchar *src_url;
+            gchar *bytes;
+            gint size;
+            GdkPixbufLoader *loader;
+            RepoData *repo;
+            gint zoom, tilex, tiley;
+            GError *error = NULL;
+
+#ifdef MAPDB_SQLITE
+            /* First check for existence. */
+            exists = mut->repo->db
+                ? mapdb_exists(mut->repo, mut->zoom,
+                        mut->tilex, mut->tiley, TRUE)
+                : FALSE;
+            if(exists && mut->update_type == MAP_UPDATE_ADD)
+            {
+                /* Map already exists, and we're not going to overwrite. */
+                break;
+            }
+#else
+            /* First check for existence. */
+            if(mut->update_type == MAP_UPDATE_ADD)
+            {
+                /* We don't want to overwrite, so check for existence. */
+                /* Map already exists, and we're not going to overwrite. */
+                if(mapdb_exists(mut->repo, mut->zoom,
+                            mut->tilex,mut->tiley, TRUE))
+                {
+                    break;
+                }
+            }
+#endif
+
+            /* First, construct the URL from which we will get the data. */
+            src_url = map_construct_url(mut->repo, mut->zoom,
+                    mut->tilex, mut->tiley);
+
+            /* Now, attempt to read the entire contents of the URL. */
+            mut->vfs_result = gnome_vfs_read_entire_file(
+                    src_url, &size, &bytes);
+            g_free(src_url);
+            if(mut->vfs_result != GNOME_VFS_OK || !bytes)
+            {
+                /* Try again. */
+                printf("Error reading URL: %s\n",
+                        gnome_vfs_result_to_string(mut->vfs_result));
+                g_free(bytes);
+                continue;
+            }
+            /* usleep(100000); DEBUG */
+
+            /* Attempt to parse the bytes into a pixbuf. */
+            loader = gdk_pixbuf_loader_new();
+            gdk_pixbuf_loader_write(loader, bytes, size, NULL);
+            gdk_pixbuf_loader_close(loader, &error);
+            if(error || (NULL == (mut->pixbuf = g_object_ref(
+                        gdk_pixbuf_loader_get_pixbuf(loader)))))
+            {
+                mut->vfs_result = GNOME_VFS_NUM_ERRORS;
+                if(mut->pixbuf)
+                    g_object_unref(mut->pixbuf);
+                mut->pixbuf = NULL;
+                g_free(bytes);
+                g_object_unref(loader);
+                printf("Error parsing pixbuf: %s\n",
+                        error ? error->message : "?");
+                continue;
+            }
+            g_object_unref(loader);
+
+            /* Copy database-relevant mut data before we release it. */
+            repo = mut->repo;
+            zoom = mut->zoom;
+            tilex = mut->tilex;
+            tiley = mut->tiley;
+
+            /* Pass the mut to the GTK thread for redrawing, but only if a
+             * redraw isn't already in the pipeline. */
+            if(mut->refresh_latch)
+            {
+                /* Wait until the latch is open. */
+                g_mutex_lock(mut->refresh_latch->mutex);
+                while(!mut->refresh_latch->is_open)
+                {
+                    g_cond_wait(mut->refresh_latch->cond,
+                            mut->refresh_latch->mutex);
+                }
+                /* Latch is open.  Decrement the number of waiters and check if
+                 * we're the last waiter to run. */
+                if(mut->refresh_latch->is_done_adding_tasks)
+                {
+                    if(++mut->refresh_latch->num_done
+                                == mut->refresh_latch->num_tasks)
+                    {
+                        /* We're the last waiter.  Free the latch resources. */
+                        g_mutex_unlock(mut->refresh_latch->mutex);
+                        g_cond_free(mut->refresh_latch->cond);
+                        g_mutex_free(mut->refresh_latch->mutex);
+                        g_slice_free(ThreadLatch, mut->refresh_latch);
+                        mut->refresh_latch = NULL;
+                    }
+                    else
+                    {
+                        /* We're not the last waiter. Signal the next waiter.*/
+                        g_cond_signal(mut->refresh_latch->cond);
+                        g_mutex_unlock(mut->refresh_latch->mutex);
+                    }
+                }
+                else
+                    g_mutex_unlock(mut->refresh_latch->mutex);
+            }
+
+            g_idle_add_full(G_PRIORITY_HIGH_IDLE,
+                    (GSourceFunc)map_download_refresh_idle, mut, NULL);
+
+            /* DO NOT USE mut FROM THIS POINT ON. */
+
+            /* Also attempt to add to the database. */
+            mapdb_update(exists, repo, zoom,
+                    tilex, tiley, bytes, size);
+
+            /* Success! */
+            g_free(bytes);
+
+            vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+            return FALSE;
+        }
+    }
+
+    /* Don't add an idle until the thread_render_map() task is done. */
+    g_idle_add_full(G_PRIORITY_HIGH_IDLE,
+            (GSourceFunc)map_download_refresh_idle, mut, NULL);
+
+    vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+    return FALSE;
+}
+
+guint
+mut_exists_hashfunc(const MapUpdateTask *a)
+{
+    gint sum = a->zoom + a->tilex + a->tiley + a->update_type;
+    return g_int_hash(&sum);
+}
+
+gboolean
+mut_exists_equalfunc(const MapUpdateTask *a, const MapUpdateTask *b)
+{
+    return (a->tilex == b->tilex
+            && a->tiley == b->tiley
+            && a->zoom == b->zoom
+            && a->update_type == b->update_type);
+}
+
+gint
+mut_priority_comparefunc(const MapUpdateTask *a, const MapUpdateTask *b)
+{
+    gint diff = (b->batch_id - a->batch_id); /* More recent ones first. */
+    if(diff)
+        return diff;
+    diff = (a->priority - b->priority); /* Lower priority numbers first. */
+    if(diff)
+        return diff;
+    return (b->id - a->id); /* Don't care - use id. */
+}
+
+static gboolean
+repoman_dialog_select(GtkWidget *widget, RepoManInfo *rmi)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+    gint curr_index = gtk_combo_box_get_active(GTK_COMBO_BOX(rmi->cmb_repos));
+    gtk_notebook_set_current_page(GTK_NOTEBOOK(rmi->notebook), curr_index);
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+repoman_dialog_browse(GtkWidget *widget, BrowseInfo *browse_info)
+{
+    GtkWidget *dialog;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    dialog = GTK_WIDGET(
+            hildon_file_chooser_dialog_new(GTK_WINDOW(browse_info->dialog),
+            GTK_FILE_CHOOSER_ACTION_OPEN));
+
+    gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(dialog), TRUE);
+    gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),
+            gtk_entry_get_text(GTK_ENTRY(browse_info->txt)));
+
+    if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(dialog)))
+    {
+        gchar *filename = gtk_file_chooser_get_filename(
+                GTK_FILE_CHOOSER(dialog));
+        gtk_entry_set_text(GTK_ENTRY(browse_info->txt), filename);
+        g_free(filename);
+    }
+
+    gtk_widget_destroy(dialog);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+repoman_dialog_rename(GtkWidget *widget, RepoManInfo *rmi)
+{
+    static GtkWidget *hbox = NULL;
+    static GtkWidget *label = NULL;
+    static GtkWidget *txt_name = NULL;
+    static GtkWidget *dialog = NULL;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(dialog == NULL)
+    {
+        dialog = gtk_dialog_new_with_buttons(_("New Name"),
+                GTK_WINDOW(rmi->dialog), GTK_DIALOG_MODAL,
+                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+                NULL);
+
+        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+                hbox = gtk_hbox_new(FALSE, 4), FALSE, FALSE, 4);
+
+        gtk_box_pack_start(GTK_BOX(hbox),
+                label = gtk_label_new(_("Name")),
+                FALSE, FALSE, 0);
+        gtk_box_pack_start(GTK_BOX(hbox),
+                txt_name = gtk_entry_new(),
+                TRUE, TRUE, 0);
+    }
+
+    {
+        gint active = gtk_combo_box_get_active(GTK_COMBO_BOX(rmi->cmb_repos));
+        RepoEditInfo *rei = g_list_nth_data(rmi->repo_edits, active);
+        gtk_entry_set_text(GTK_ENTRY(txt_name), rei->name);
+    }
+
+    gtk_widget_show_all(dialog);
+
+    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
+    {
+        gint active = gtk_combo_box_get_active(GTK_COMBO_BOX(rmi->cmb_repos));
+        RepoEditInfo *rei = g_list_nth_data(rmi->repo_edits, active);
+        g_free(rei->name);
+        rei->name = g_strdup(gtk_entry_get_text(GTK_ENTRY(txt_name)));
+        gtk_combo_box_insert_text(GTK_COMBO_BOX(rmi->cmb_repos),
+                active, g_strdup(rei->name));
+        gtk_combo_box_set_active(GTK_COMBO_BOX(rmi->cmb_repos), active);
+        gtk_combo_box_remove_text(GTK_COMBO_BOX(rmi->cmb_repos), active + 1);
+        break;
+    }
+
+    gtk_widget_hide(dialog);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static void
+repoman_delete(RepoManInfo *rmi, gint index)
+{
+    gtk_combo_box_remove_text(GTK_COMBO_BOX(rmi->cmb_repos), index);
+    gtk_notebook_remove_page(GTK_NOTEBOOK(rmi->notebook), index);
+    rmi->repo_edits = g_list_remove_link(
+            rmi->repo_edits,
+            g_list_nth(rmi->repo_edits, index));
+}
+
+static gboolean
+repoman_dialog_delete(GtkWidget *widget, RepoManInfo *rmi, gint index)
+{
+    gchar buffer[100];
+    GtkWidget *confirm;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(gtk_tree_model_iter_n_children(GTK_TREE_MODEL(
+                    gtk_combo_box_get_model(GTK_COMBO_BOX(rmi->cmb_repos))),
+                                NULL) <= 1)
+    {
+        popup_error(rmi->dialog,
+                _("Cannot delete the last repository - there must be at"
+                " lease one repository."));
+        vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+        return TRUE;
+    }
+
+    snprintf(buffer, sizeof(buffer), "%s:\n%s\n",
+            _("Confirm delete of repository"),
+            gtk_combo_box_get_active_text(GTK_COMBO_BOX(rmi->cmb_repos)));
+
+    confirm = hildon_note_new_confirmation(GTK_WINDOW(rmi->dialog),buffer);
+
+    if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm)))
+    {
+        gint active = gtk_combo_box_get_active(GTK_COMBO_BOX(rmi->cmb_repos));
+        repoman_delete(rmi, active);
+        gtk_combo_box_set_active(GTK_COMBO_BOX(rmi->cmb_repos),
+                MAX(0, index - 1));
+    }
+
+    gtk_widget_destroy(confirm);
+
+    return TRUE;
+}
+
+static RepoEditInfo*
+repoman_dialog_add_repo(RepoManInfo *rmi, gchar *name)
+{
+    GtkWidget *vbox;
+    GtkWidget *table;
+    GtkWidget *label;
+    GtkWidget *hbox;
+    RepoEditInfo *rei = g_new(RepoEditInfo, 1);
+    printf("%s(%s)\n", __PRETTY_FUNCTION__, name);
+
+    rei->name = name;
+
+    /* Maps page. */
+    gtk_notebook_append_page(GTK_NOTEBOOK(rmi->notebook),
+            vbox = gtk_vbox_new(FALSE, 4),
+            gtk_label_new(name));
+
+    /* Prevent destruction of notebook page, because the destruction causes
+     * a seg fault (!?!?) */
+    gtk_object_ref(GTK_OBJECT(vbox));
+
+    gtk_box_pack_start(GTK_BOX(vbox),
+            table = gtk_table_new(2, 2, FALSE),
+            FALSE, FALSE, 0);
+    /* Map download URI. */
+    gtk_table_attach(GTK_TABLE(table),
+            label = gtk_label_new(_("URL Format")),
+            0, 1, 0, 1, GTK_FILL, 0, 2, 4);
+    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+    gtk_table_attach(GTK_TABLE(table),
+            rei->txt_url = gtk_entry_new(),
+            1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+
+    /* Map Directory. */
+    gtk_table_attach(GTK_TABLE(table),
+            label = gtk_label_new(_("Cache DB")),
+            0, 1, 1, 2, GTK_FILL, 0, 2, 4);
+    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+    gtk_table_attach(GTK_TABLE(table),
+            hbox = gtk_hbox_new(FALSE, 4),
+            1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+    gtk_box_pack_start(GTK_BOX(hbox),
+            rei->txt_db_filename = gtk_entry_new(),
+            TRUE, TRUE, 0);
+    gtk_box_pack_start(GTK_BOX(hbox),
+            rei->btn_browse = gtk_button_new_with_label(_("Browse...")),
+            FALSE, FALSE, 0);
+
+    /* Initialize cache dir */
+    {
+        gchar buffer[BUFFER_SIZE];
+        snprintf(buffer, sizeof(buffer), "%s.db", name);
+        gchar *db_base = gnome_vfs_expand_initial_tilde(
+                REPO_DEFAULT_CACHE_BASE);
+        gchar *db_filename = gnome_vfs_uri_make_full_from_relative(
+                db_base, buffer);
+        gtk_entry_set_text(GTK_ENTRY(rei->txt_db_filename), db_filename);
+        g_free(db_filename);
+        g_free(db_base);
+    }
+
+    gtk_box_pack_start(GTK_BOX(vbox),
+            table = gtk_table_new(3, 2, FALSE),
+            FALSE, FALSE, 0);
+
+    /* Download Zoom Steps. */
+    gtk_table_attach(GTK_TABLE(table),
+            label = gtk_label_new(_("Download Zoom Steps")),
+            0, 1, 0, 1, GTK_FILL, 0, 2, 4);
+    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+    gtk_table_attach(GTK_TABLE(table),
+            label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
+            1, 2, 0, 1, GTK_FILL, 0, 2, 4);
+    gtk_container_add(GTK_CONTAINER(label),
+            rei->num_dl_zoom_steps = hildon_controlbar_new());
+    hildon_controlbar_set_range(
+            HILDON_CONTROLBAR(rei->num_dl_zoom_steps), 1, 4);
+    hildon_controlbar_set_value(HILDON_CONTROLBAR(rei->num_dl_zoom_steps),
+            REPO_DEFAULT_DL_ZOOM_STEPS);
+    force_min_visible_bars(HILDON_CONTROLBAR(rei->num_dl_zoom_steps), 1);
+
+    /* Download Zoom Steps. */
+    gtk_table_attach(GTK_TABLE(table),
+            label = gtk_label_new(_("View Zoom Steps")),
+            0, 1, 1, 2, GTK_FILL, 0, 2, 4);
+    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+    gtk_table_attach(GTK_TABLE(table),
+            label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
+            1, 2, 1, 2, GTK_FILL, 0, 2, 4);
+    gtk_container_add(GTK_CONTAINER(label),
+            rei->num_view_zoom_steps = hildon_controlbar_new());
+    hildon_controlbar_set_range(
+            HILDON_CONTROLBAR(rei->num_view_zoom_steps), 1, 4);
+    hildon_controlbar_set_value(HILDON_CONTROLBAR(rei->num_view_zoom_steps),
+            REPO_DEFAULT_VIEW_ZOOM_STEPS);
+    force_min_visible_bars(HILDON_CONTROLBAR(rei->num_view_zoom_steps), 1);
+
+    gtk_table_attach(GTK_TABLE(table),
+            label = gtk_vseparator_new(),
+            2, 3, 0, 2, GTK_FILL, GTK_FILL, 4, 4);
+
+    /* Double-size. */
+    gtk_table_attach(GTK_TABLE(table),
+            rei->chk_double_size = gtk_check_button_new_with_label(
+                _("Double Pixels")),
+            3, 4, 0, 1, GTK_FILL, GTK_FILL, 0, 4);
+    gtk_toggle_button_set_active(
+            GTK_TOGGLE_BUTTON(rei->chk_double_size), FALSE);
+
+    /* Next-able */
+    gtk_table_attach(GTK_TABLE(table),
+            rei->chk_nextable = gtk_check_button_new_with_label(
+                _("Next-able")),
+            3, 4, 1, 2, GTK_FILL, GTK_FILL, 0, 4);
+    gtk_toggle_button_set_active(
+            GTK_TOGGLE_BUTTON(rei->chk_nextable), TRUE);
+
+    rmi->repo_edits = g_list_append(rmi->repo_edits, rei);
+
+    /* Connect signals. */
+    rei->browse_info.dialog = rmi->dialog;
+    rei->browse_info.txt = rei->txt_db_filename;
+    g_signal_connect(G_OBJECT(rei->btn_browse), "clicked",
+                      G_CALLBACK(repoman_dialog_browse),
+                      &rei->browse_info);
+
+    gtk_widget_show_all(vbox);
+
+    gtk_combo_box_append_text(GTK_COMBO_BOX(rmi->cmb_repos), name);
+    gtk_combo_box_set_active(GTK_COMBO_BOX(rmi->cmb_repos),
+            gtk_tree_model_iter_n_children(GTK_TREE_MODEL(
+                    gtk_combo_box_get_model(GTK_COMBO_BOX(rmi->cmb_repos))),
+                NULL) - 1);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return rei;
+}
+
+static gboolean
+repoman_dialog_new(GtkWidget *widget, RepoManInfo *rmi)
+{
+    static GtkWidget *hbox = NULL;
+    static GtkWidget *label = NULL;
+    static GtkWidget *txt_name = NULL;
+    static GtkWidget *dialog = NULL;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(dialog == NULL)
+    {
+        dialog = gtk_dialog_new_with_buttons(_("New Repository"),
+                GTK_WINDOW(rmi->dialog), GTK_DIALOG_MODAL,
+                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+                NULL);
+
+        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+                hbox = gtk_hbox_new(FALSE, 4), FALSE, FALSE, 4);
+
+        gtk_box_pack_start(GTK_BOX(hbox),
+                label = gtk_label_new(_("Name")),
+                FALSE, FALSE, 0);
+        gtk_box_pack_start(GTK_BOX(hbox),
+                txt_name = gtk_entry_new(),
+                TRUE, TRUE, 0);
+    }
+
+    gtk_entry_set_text(GTK_ENTRY(txt_name), "");
+
+    gtk_widget_show_all(dialog);
+
+    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
+    {
+        repoman_dialog_add_repo(rmi,
+                g_strdup(gtk_entry_get_text(GTK_ENTRY(txt_name))));
+        break;
+    }
+
+    gtk_widget_hide(dialog);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+repoman_reset(GtkWidget *widget, RepoManInfo *rmi)
+{
+    GtkWidget *confirm;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    confirm = hildon_note_new_confirmation(GTK_WINDOW(rmi->dialog),
+            _("Replace all repositories with the default repository?"));
+
+    if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm)))
+    {
+        /* First, delete all existing repositories. */
+        while(rmi->repo_edits)
+            repoman_delete(rmi, 0);
+
+        /* Now, add the default repository. */
+        repoman_dialog_add_repo(rmi, REPO_DEFAULT_NAME);
+        gtk_entry_set_text(
+                GTK_ENTRY(((RepoEditInfo*)rmi->repo_edits->data)->txt_url),
+                REPO_DEFAULT_MAP_URI);
+
+        gtk_combo_box_set_active(GTK_COMBO_BOX(rmi->cmb_repos), 0);
+    }
+    gtk_widget_destroy(confirm);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+repoman_download(GtkWidget *widget, RepoManInfo *rmi)
+{
+    GtkWidget *confirm;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    confirm = hildon_note_new_confirmation(
+            GTK_WINDOW(rmi->dialog),
+            _("Maemo Mapper will now download and add a list of "
+                "possibly-duplicate repositories from the internet.  "
+                "Continue?"));
+
+    if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm)))
+    {
+        gchar *bytes;
+        gchar *head;
+        gchar *tail;
+        gint size;
+        GnomeVFSResult vfs_result;
+        printf("%s()\n", __PRETTY_FUNCTION__);
+
+        /* Get repo config file from www.gnuite.com. */
+        if(GNOME_VFS_OK != (vfs_result = gnome_vfs_read_entire_file(
+                    "http://www.gnuite.com/nokia770/maemo-mapper/repos.txt",
+                    &size, &bytes)))
+        {
+            popup_error(rmi->dialog,
+                    _("An error occurred while retrieving the repositories.  "
+                        "The web service may be temporarily down."));
+            g_printerr("Error while download repositories: %s\n",
+                    gnome_vfs_result_to_string(vfs_result));
+        }
+        /* Parse each line as a reposotory. */
+        else
+        {
+            for(head = bytes; head && *head; head = tail)
+            {
+                RepoData *rd;
+                RepoEditInfo *rei;
+                tail = strchr(head, '\n');
+                *tail++ = '\0';
+                rd = settings_parse_repo(head);
+                rei = repoman_dialog_add_repo(
+                        rmi, g_strdup(rd->name));
+                /* Initialize fields with data from the RepoData object. */
+                gtk_entry_set_text(GTK_ENTRY(rei->txt_url), rd->url);
+                gtk_entry_set_text(GTK_ENTRY(rei->txt_db_filename),
+                        rd->db_filename);
+                hildon_controlbar_set_value(
+                        HILDON_CONTROLBAR(rei->num_dl_zoom_steps),
+                        rd->dl_zoom_steps);
+                hildon_controlbar_set_value(
+                        HILDON_CONTROLBAR(rei->num_view_zoom_steps),
+                        rd->view_zoom_steps);
+                gtk_toggle_button_set_active(
+                        GTK_TOGGLE_BUTTON(rei->chk_double_size),
+                        rd->double_size);
+                gtk_toggle_button_set_active(
+                        GTK_TOGGLE_BUTTON(rei->chk_nextable),
+                        rd->nextable);
+            }
+            g_free(bytes);
+        }
+    }
+    gtk_widget_destroy(confirm);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+gboolean
+repoman_dialog()
+{
+    static RepoManInfo rmi;
+    static GtkWidget *dialog = NULL;
+    static GtkWidget *hbox = NULL;
+    static GtkWidget *btn_rename = NULL;
+    static GtkWidget *btn_delete = NULL;
+    static GtkWidget *btn_new = NULL;
+    static GtkWidget *btn_reset = NULL;
+    static GtkWidget *btn_download = NULL;
+    gint i, curr_repo_index = 0;
+    GList *curr;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(dialog == NULL)
+    {
+        rmi.dialog = dialog = gtk_dialog_new_with_buttons(
+                _("Manage Repositories"),
+                GTK_WINDOW(_window), GTK_DIALOG_MODAL,
+                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+                NULL);
+
+        /* Enable the help button. */
+        ossohelp_dialog_help_enable(
+                GTK_DIALOG(dialog), HELP_ID_REPOMAN, _osso);
+
+        /* Reset button. */
+        gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
+                btn_reset = gtk_button_new_with_label(_("Reset...")));
+        g_signal_connect(G_OBJECT(btn_reset), "clicked",
+                          G_CALLBACK(repoman_reset), &rmi);
+
+        /* Download button. */
+        gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
+                btn_download = gtk_button_new_with_label(_("Download...")));
+        g_signal_connect(G_OBJECT(btn_download), "clicked",
+                          G_CALLBACK(repoman_download), &rmi);
+
+        /* Cancel button. */
+        gtk_dialog_add_button(GTK_DIALOG(dialog),
+                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
+
+        hbox = gtk_hbox_new(FALSE, 4);
+
+        gtk_box_pack_start(GTK_BOX(hbox),
+                rmi.cmb_repos = gtk_combo_box_new_text(), TRUE, TRUE, 4);
+
+        gtk_box_pack_start(GTK_BOX(hbox),
+                gtk_vseparator_new(), FALSE, FALSE, 4);
+        gtk_box_pack_start(GTK_BOX(hbox),
+                btn_rename = gtk_button_new_with_label(_("Rename...")),
+                FALSE, FALSE, 4);
+        gtk_box_pack_start(GTK_BOX(hbox),
+                btn_delete = gtk_button_new_with_label(_("Delete...")),
+                FALSE, FALSE, 4);
+        gtk_box_pack_start(GTK_BOX(hbox),
+                btn_new = gtk_button_new_with_label(_("New...")),
+                FALSE, FALSE, 4);
+
+        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+                hbox, FALSE, FALSE, 4);
+
+        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+                gtk_hseparator_new(), TRUE, TRUE, 4);
+        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+                rmi.notebook = gtk_notebook_new(), TRUE, TRUE, 4);
+
+        gtk_notebook_set_show_tabs(GTK_NOTEBOOK(rmi.notebook), FALSE);
+        gtk_notebook_set_show_border(GTK_NOTEBOOK(rmi.notebook), FALSE);
+
+        rmi.repo_edits = NULL;
+
+        /* Connect signals. */
+        g_signal_connect(G_OBJECT(btn_rename), "clicked",
+                G_CALLBACK(repoman_dialog_rename), &rmi);
+        g_signal_connect(G_OBJECT(btn_delete), "clicked",
+                G_CALLBACK(repoman_dialog_delete), &rmi);
+        g_signal_connect(G_OBJECT(btn_new), "clicked",
+                G_CALLBACK(repoman_dialog_new), &rmi);
+        g_signal_connect(G_OBJECT(rmi.cmb_repos), "changed",
+                G_CALLBACK(repoman_dialog_select), &rmi);
+    }
+
+    /* Populate combo box and pages in notebook. */
+    for(i = 0, curr = _repo_list; curr; curr = curr->next, i++)
+    {
+        RepoData *rd = (RepoData*)curr->data;
+        RepoEditInfo *rei = repoman_dialog_add_repo(&rmi, g_strdup(rd->name));
+
+        /* Initialize fields with data from the RepoData object. */
+        gtk_entry_set_text(GTK_ENTRY(rei->txt_url), rd->url);
+        gtk_entry_set_text(GTK_ENTRY(rei->txt_db_filename),
+                rd->db_filename);
+        hildon_controlbar_set_value(
+                HILDON_CONTROLBAR(rei->num_dl_zoom_steps),
+                rd->dl_zoom_steps);
+        hildon_controlbar_set_value(
+                HILDON_CONTROLBAR(rei->num_view_zoom_steps),
+                rd->view_zoom_steps);
+        gtk_toggle_button_set_active(
+                GTK_TOGGLE_BUTTON(rei->chk_double_size),
+                rd->double_size);
+        gtk_toggle_button_set_active(
+                GTK_TOGGLE_BUTTON(rei->chk_nextable),
+                rd->nextable);
+        if(rd == _curr_repo)
+            curr_repo_index = i;
+    }
+
+    gtk_combo_box_set_active(GTK_COMBO_BOX(rmi.cmb_repos), curr_repo_index);
+    gtk_notebook_set_current_page(GTK_NOTEBOOK(rmi.notebook), curr_repo_index);
+
+    gtk_widget_show_all(dialog);
+
+    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
+    {
+        /* Iterate through repos and verify each. */
+        gint i;
+        GList *curr;
+        gchar *old_curr_repo_name = _curr_repo->name;
+
+        /* We're good to replace.  Remove old _repo_list menu items. */
+        menu_maps_remove_repos();
+        /* But keep the repo list in memory, in case downloads are using it. */
+        _repo_list = NULL;
+
+        /* Write new _repo_list. */
+        curr_repo_index = gtk_combo_box_get_active(
+                GTK_COMBO_BOX(rmi.cmb_repos));
+        _curr_repo = NULL;
+        for(i = 0, curr = rmi.repo_edits; curr; curr = curr->next, i++)
+        {
+            RepoEditInfo *rei = curr->data;
+            RepoData *rd = g_new(RepoData, 1);
+            rd->name = g_strdup(rei->name);
+            rd->url = g_strdup(gtk_entry_get_text(GTK_ENTRY(rei->txt_url)));
+            rd->db_filename = gnome_vfs_expand_initial_tilde(
+                    gtk_entry_get_text(GTK_ENTRY(rei->txt_db_filename)));
+            rd->dl_zoom_steps = hildon_controlbar_get_value(
+                    HILDON_CONTROLBAR(rei->num_dl_zoom_steps));
+            rd->view_zoom_steps = hildon_controlbar_get_value(
+                    HILDON_CONTROLBAR(rei->num_view_zoom_steps));
+            rd->double_size = gtk_toggle_button_get_active(
+                    GTK_TOGGLE_BUTTON(rei->chk_double_size));
+            rd->nextable = gtk_toggle_button_get_active(
+                    GTK_TOGGLE_BUTTON(rei->chk_nextable));
+            set_repo_type(rd);
+
+            _repo_list = g_list_append(_repo_list, rd);
+
+            if(!_curr_repo && !strcmp(old_curr_repo_name, rd->name))
+                repo_set_curr(rd);
+            else if(i == curr_repo_index)
+                repo_set_curr(rd);
+        }
+        if(!_curr_repo)
+            repo_set_curr((RepoData*)g_list_first(_repo_list)->data);
+        menu_maps_add_repos();
+
+        settings_save();
+        break;
+    }
+
+    gtk_widget_hide(dialog);
+
+    /* Clear out the notebook entries. */
+    while(rmi.repo_edits)
+        repoman_delete(&rmi, 0);
+
+    map_set_zoom(_zoom); /* make sure we're at an appropriate zoom level. */
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+mapman_by_area(gfloat start_lat, gfloat start_lon,
+        gfloat end_lat, gfloat end_lon, MapmanInfo *mapman_info,
+        MapUpdateType update_type,
+        gint download_batch_id)
+{
+    gint start_unitx, start_unity, end_unitx, end_unity;
+    gint num_maps = 0;
+    gint z;
+    gchar buffer[80];
+    GtkWidget *confirm;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    latlon2unit(start_lat, start_lon, start_unitx, start_unity);
+    latlon2unit(end_lat, end_lon, end_unitx, end_unity);
+
+    /* Swap if they specified flipped lats or lons. */
+    if(start_unitx > end_unitx)
+    {
+        gint swap = start_unitx;
+        start_unitx = end_unitx;
+        end_unitx = swap;
+    }
+    if(start_unity > end_unity)
+    {
+        gint swap = start_unity;
+        start_unity = end_unity;
+        end_unity = swap;
+    }
+
+    /* First, get the number of maps to download. */
+    for(z = MAX_ZOOM; z-- != 0; )
+    {
+        if(gtk_toggle_button_get_active(
+                    GTK_TOGGLE_BUTTON(mapman_info->chk_zoom_levels[z])))
+        {
+            gint start_tilex, start_tiley, end_tilex, end_tiley;
+            start_tilex = unit2ztile(start_unitx, z);
+            start_tiley = unit2ztile(start_unity, z);
+            end_tilex = unit2ztile(end_unitx, z);
+            end_tiley = unit2ztile(end_unity, z);
+            num_maps += (end_tilex - start_tilex + 1)
+                * (end_tiley - start_tiley + 1);
+        }
+    }
+
+    if(update_type == MAP_UPDATE_DELETE)
+    {
+        snprintf(buffer, sizeof(buffer), "%s %d %s", _("Confirm DELETION of"),
+                num_maps, _("maps "));
+    }
+    else
+    {
+        snprintf(buffer, sizeof(buffer),
+                "%s %d %s\n(%s %.2f MB)\n", _("Confirm download of"),
+                num_maps, _("maps"), _("up to about"),
+                num_maps * (strstr(_curr_repo->url, "%s") ? 18e-3 : 6e-3));
+    }
+    confirm = hildon_note_new_confirmation(
+            GTK_WINDOW(mapman_info->dialog), buffer);
+
+    if(GTK_RESPONSE_OK != gtk_dialog_run(GTK_DIALOG(confirm)))
+    {
+        gtk_widget_destroy(confirm);
+        vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+        return FALSE;
+    }
+    for(z = MAX_ZOOM; z-- != 0; )
+    {
+        if(gtk_toggle_button_get_active(
+                    GTK_TOGGLE_BUTTON(mapman_info->chk_zoom_levels[z])))
+        {
+            gint start_tilex, start_tiley, end_tilex, end_tiley;
+            gint tilex, tiley;
+            start_tilex = unit2ztile(start_unitx, z);
+            start_tiley = unit2ztile(start_unity, z);
+            end_tilex = unit2ztile(end_unitx, z);
+            end_tiley = unit2ztile(end_unity, z);
+            for(tiley = start_tiley; tiley <= end_tiley; tiley++)
+            {
+                for(tilex = start_tilex; tilex <= end_tilex; tilex++)
+                {
+                    /* Make sure this tile is even possible. */
+                    if((unsigned)tilex < unit2ztile(WORLD_SIZE_UNITS, z)
+                      && (unsigned)tiley < unit2ztile(WORLD_SIZE_UNITS, z))
+                    {
+                        mapdb_initiate_update(_curr_repo, z, tilex, tiley,
+                                update_type, download_batch_id,
+                                (abs(tilex - unit2tile(_next_center.unitx))
+                                 + abs(tiley - unit2tile(_next_center.unity))),
+                                NULL);
+                    }
+                }
+            }
+        }
+    }
+    gtk_widget_destroy(confirm);
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+mapman_by_route(MapmanInfo *mapman_info, MapUpdateType update_type,
+        gint download_batch_id)
+{
+    GtkWidget *confirm;
+    gint prev_tilex, prev_tiley, num_maps = 0, z;
+    Point *curr;
+    gchar buffer[80];
+    gint radius = hildon_number_editor_get_value(
+            HILDON_NUMBER_EDITOR(mapman_info->num_route_radius));
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    /* First, get the number of maps to download. */
+    for(z = 0; z < MAX_ZOOM; z++)
+    {
+        if(gtk_toggle_button_get_active(
+                    GTK_TOGGLE_BUTTON(mapman_info->chk_zoom_levels[z])))
+        {
+            prev_tilex = 0;
+            prev_tiley = 0;
+            for(curr = _route.head - 1; curr++ != _route.tail; )
+            {
+                if(curr->unity)
+                {
+                    gint tilex = unit2ztile(curr->unitx, z);
+                    gint tiley = unit2ztile(curr->unity, z);
+                    if(tilex != prev_tilex || tiley != prev_tiley)
+                    {
+                        if(prev_tiley)
+                            num_maps += (abs((gint)tilex - prev_tilex) + 1)
+                                * (abs((gint)tiley - prev_tiley) + 1) - 1;
+                        prev_tilex = tilex;
+                        prev_tiley = tiley;
+                    }
+                }
+            }
+        }
+    }
+    num_maps *= 0.625 * pow(radius + 1, 1.85);
+
+    if(update_type == MAP_UPDATE_DELETE)
+    {
+        snprintf(buffer, sizeof(buffer), "%s %s %d %s",
+                _("Confirm DELETION of"), _("about"),
+                num_maps, _("maps "));
+    }
+    else
+    {
+        snprintf(buffer, sizeof(buffer),
+                "%s %s %d %s\n(%s %.2f MB)\n", _("Confirm download of"),
+                _("about"),
+                num_maps, _("maps"), _("up to about"),
+                num_maps * (strstr(_curr_repo->url, "%s") ? 18e-3 : 6e-3));
+    }
+    confirm = hildon_note_new_confirmation(
+            GTK_WINDOW(mapman_info->dialog), buffer);
+
+    if(GTK_RESPONSE_OK != gtk_dialog_run(GTK_DIALOG(confirm)))
+    {
+        gtk_widget_destroy(confirm);
+        vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+        return FALSE;
+    }
+
+    /* Now, do the actual download. */
+    for(z = 0; z < MAX_ZOOM; z++)
+    {
+        if(gtk_toggle_button_get_active(
+                    GTK_TOGGLE_BUTTON(mapman_info->chk_zoom_levels[z])))
+        {
+            prev_tilex = 0;
+            prev_tiley = 0;
+            for(curr = _route.head - 1; curr++ != _route.tail; )
+            {
+                if(curr->unity)
+                {
+                    gint tilex = unit2ztile(curr->unitx, z);
+                    gint tiley = unit2ztile(curr->unity, z);
+                    if(tilex != prev_tilex || tiley != prev_tiley)
+                    {
+                        gint minx, miny, maxx, maxy, x, y;
+                        if(prev_tiley != 0)
+                        {
+                            minx = MIN(tilex, prev_tilex) - radius;
+                            miny = MIN(tiley, prev_tiley) - radius;
+                            maxx = MAX(tilex, prev_tilex) + radius;
+                            maxy = MAX(tiley, prev_tiley) + radius;
+                        }
+                        else
+                        {
+                            minx = tilex - radius;
+                            miny = tiley - radius;
+                            maxx = tilex + radius;
+                            maxy = tiley + radius;
+                        }
+                        for(x = minx; x <= maxx; x++)
+                        {
+                            for(y = miny; y <= maxy; y++)
+                            {
+                                if((unsigned)tilex
+                                        < unit2ztile(WORLD_SIZE_UNITS, z)
+                                  && (unsigned)tiley
+                                        < unit2ztile(WORLD_SIZE_UNITS, z))
+                                {
+                                    mapdb_initiate_update(_curr_repo, z, x, y,
+                                        update_type, download_batch_id,
+                                        (abs(tilex - unit2tile(
+                                                 _next_center.unitx))
+                                         + abs(tiley - unit2tile(
+                                                 _next_center.unity))),
+                                        NULL);
+                                }
+                            }
+                        }
+                        prev_tilex = tilex;
+                        prev_tiley = tiley;
+                    }
+                }
+            }
+        }
+    }
+    _route_dl_radius = radius;
+    gtk_widget_destroy(confirm);
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static void
+mapman_clear(GtkWidget *widget, MapmanInfo *mapman_info)
+{
+    gint z;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+    if(gtk_notebook_get_current_page(GTK_NOTEBOOK(mapman_info->notebook)))
+        /* This is the second page (the "Zoom" page) - clear the checks. */
+        for(z = 0; z < MAX_ZOOM; z++)
+            gtk_toggle_button_set_active(
+                    GTK_TOGGLE_BUTTON(mapman_info->chk_zoom_levels[z]), FALSE);
+    else
+    {
+        /* This is the first page (the "Area" page) - clear the text fields. */
+        gtk_entry_set_text(GTK_ENTRY(mapman_info->txt_topleft_lat), "");
+        gtk_entry_set_text(GTK_ENTRY(mapman_info->txt_topleft_lon), "");
+        gtk_entry_set_text(GTK_ENTRY(mapman_info->txt_botright_lat), "");
+        gtk_entry_set_text(GTK_ENTRY(mapman_info->txt_botright_lon), "");
+    }
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+void mapman_update_state(GtkWidget *widget, MapmanInfo *mapman_info)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+    gtk_widget_set_sensitive( mapman_info->chk_overwrite,
+            gtk_toggle_button_get_active(
+                GTK_TOGGLE_BUTTON(mapman_info->rad_download)));
+
+    if(gtk_toggle_button_get_active(
+                GTK_TOGGLE_BUTTON(mapman_info->rad_by_area)))
+        gtk_widget_show(mapman_info->tbl_area);
+    else if(gtk_notebook_get_n_pages(GTK_NOTEBOOK(mapman_info->notebook)) == 3)
+        gtk_widget_hide(mapman_info->tbl_area);
+
+    gtk_widget_set_sensitive(mapman_info->num_route_radius,
+            gtk_toggle_button_get_active(
+                GTK_TOGGLE_BUTTON(mapman_info->rad_by_route)));
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+gboolean
+mapman_dialog()
+{
+    static GtkWidget *dialog = NULL;
+    static GtkWidget *vbox = NULL;
+    static GtkWidget *hbox = NULL;
+    static GtkWidget *table = NULL;
+    static GtkWidget *label = NULL;
+    static GtkWidget *button = NULL;
+    static GtkWidget *lbl_gps_lat = NULL;
+    static GtkWidget *lbl_gps_lon = NULL;
+    static GtkWidget *lbl_center_lat = NULL;
+    static GtkWidget *lbl_center_lon = NULL;
+    static MapmanInfo mapman_info;
+    gchar buffer[80];
+    gfloat lat, lon;
+    gint z;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(!_curr_repo->db)
+    {
+        popup_error(_window, "To manage maps, you must set a valid repository "
+                "database filename in the \"Manage Repositories\" dialog.");
+        vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+        return TRUE;
+    }
+
+    if(dialog == NULL)
+    {
+        mapman_info.dialog = dialog = gtk_dialog_new_with_buttons(
+                _("Manage Maps"),
+                GTK_WINDOW(_window), GTK_DIALOG_MODAL,
+                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+                NULL);
+
+        /* Enable the help button. */
+        ossohelp_dialog_help_enable(
+                GTK_DIALOG(mapman_info.dialog), HELP_ID_MAPMAN, _osso);
+
+        /* Clear button. */
+        gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
+                button = gtk_button_new_with_label(_("Clear")));
+        g_signal_connect(G_OBJECT(button), "clicked",
+                          G_CALLBACK(mapman_clear), &mapman_info);
+
+        /* Cancel button. */
+        gtk_dialog_add_button(GTK_DIALOG(dialog),
+                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
+
+        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+                mapman_info.notebook = gtk_notebook_new(), TRUE, TRUE, 0);
+
+        /* Setup page. */
+        gtk_notebook_append_page(GTK_NOTEBOOK(mapman_info.notebook),
+                vbox = gtk_vbox_new(FALSE, 2),
+                label = gtk_label_new(_("Setup")));
+        gtk_notebook_set_tab_label_packing(
+                GTK_NOTEBOOK(mapman_info.notebook), vbox,
+                FALSE, FALSE, GTK_PACK_START);
+
+        gtk_box_pack_start(GTK_BOX(vbox),
+                hbox = gtk_hbox_new(FALSE, 4),
+                FALSE, FALSE, 0);
+        gtk_box_pack_start(GTK_BOX(hbox),
+                mapman_info.rad_download = gtk_radio_button_new_with_label(
+                    NULL,_("Download Maps")),
+                FALSE, FALSE, 0);
+        gtk_box_pack_start(GTK_BOX(hbox),
+                label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
+                FALSE, FALSE, 0);
+        gtk_container_add(GTK_CONTAINER(label),
+                mapman_info.chk_overwrite
+                        = gtk_check_button_new_with_label(_("Overwrite"))),
+
+        gtk_box_pack_start(GTK_BOX(vbox),
+                mapman_info.rad_delete
+                        = gtk_radio_button_new_with_label_from_widget(
+                            GTK_RADIO_BUTTON(mapman_info.rad_download),
+                            _("Delete Maps")),
+                FALSE, FALSE, 0);
+
+        gtk_box_pack_start(GTK_BOX(vbox),
+                gtk_hseparator_new(),
+                FALSE, FALSE, 0);
+
+        gtk_box_pack_start(GTK_BOX(vbox),
+                mapman_info.rad_by_area
+                        = gtk_radio_button_new_with_label(NULL,
+                            _("By Area (see tab)")),
+                FALSE, FALSE, 0);
+        gtk_box_pack_start(GTK_BOX(vbox),
+                hbox = gtk_hbox_new(FALSE, 4),
+                FALSE, FALSE, 0);
+        gtk_box_pack_start(GTK_BOX(hbox),
+                mapman_info.rad_by_route
+                        = gtk_radio_button_new_with_label_from_widget(
+                            GTK_RADIO_BUTTON(mapman_info.rad_by_area),
+                            _("Along Route - Radius (tiles):")),
+                FALSE, FALSE, 0);
+        gtk_widget_set_sensitive(mapman_info.rad_by_route,
+                _route.head != _route.tail);
+        gtk_box_pack_start(GTK_BOX(hbox),
+                mapman_info.num_route_radius = hildon_number_editor_new(0,100),
+                FALSE, FALSE, 0);
+        hildon_number_editor_set_value(
+                HILDON_NUMBER_EDITOR(mapman_info.num_route_radius),
+                _route_dl_radius);
+
+
+        /* Zoom page. */
+        gtk_notebook_append_page(GTK_NOTEBOOK(mapman_info.notebook),
+                table = gtk_table_new(5, 5, FALSE),
+                label = gtk_label_new(_("Zoom")));
+        gtk_notebook_set_tab_label_packing(
+                GTK_NOTEBOOK(mapman_info.notebook), table,
+                FALSE, FALSE, GTK_PACK_START);
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(
+                    _("Zoom Levels to Download: (0 = most detail)")),
+                0, 4, 0, 1, GTK_FILL, 0, 4, 0);
+        gtk_misc_set_alignment(GTK_MISC(label), 0.f, 0.5f);
+        for(z = 0; z < MAX_ZOOM; z++)
+        {
+            snprintf(buffer, sizeof(buffer), "%d", z);
+            gtk_table_attach(GTK_TABLE(table),
+                    mapman_info.chk_zoom_levels[z]
+                            = gtk_check_button_new_with_label(buffer),
+                    z / 4, z / 4 + 1, z % 4 + 1, z % 4 + 2,
+                    GTK_FILL, 0, 4, 0);
+        }
+
+        /* Area page. */
+        gtk_notebook_append_page(GTK_NOTEBOOK(mapman_info.notebook),
+            mapman_info.tbl_area = gtk_table_new(5, 3, FALSE),
+            label = gtk_label_new(_("Area")));
+
+        /* Label Columns. */
+        gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
+                label = gtk_label_new(_("Latitude")),
+                1, 2, 0, 1, GTK_FILL, 0, 4, 0);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
+                label = gtk_label_new(_("Longitude")),
+                2, 3, 0, 1, GTK_FILL, 0, 4, 0);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+
+        /* GPS. */
+        gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
+                label = gtk_label_new(_("GPS Location")),
+                0, 1, 1, 2, GTK_FILL, 0, 4, 0);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
+                lbl_gps_lat = gtk_label_new(""),
+                1, 2, 1, 2, GTK_FILL, 0, 4, 0);
+        gtk_label_set_selectable(GTK_LABEL(lbl_gps_lat), TRUE);
+        gtk_misc_set_alignment(GTK_MISC(lbl_gps_lat), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
+                lbl_gps_lon = gtk_label_new(""),
+                2, 3, 1, 2, GTK_FILL, 0, 4, 0);
+        gtk_label_set_selectable(GTK_LABEL(lbl_gps_lon), TRUE);
+        gtk_misc_set_alignment(GTK_MISC(lbl_gps_lon), 1.f, 0.5f);
+
+        /* Center. */
+        gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
+                label = gtk_label_new(_("View Center")),
+                0, 1, 2, 3, GTK_FILL, 0, 4, 0);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
+                lbl_center_lat = gtk_label_new(""),
+                1, 2, 2, 3, GTK_FILL, 0, 4, 0);
+        gtk_label_set_selectable(GTK_LABEL(lbl_center_lat), TRUE);
+        gtk_misc_set_alignment(GTK_MISC(lbl_center_lat), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
+                lbl_center_lon = gtk_label_new(""),
+                2, 3, 2, 3, GTK_FILL, 0, 4, 0);
+        gtk_label_set_selectable(GTK_LABEL(lbl_center_lon), TRUE);
+        gtk_misc_set_alignment(GTK_MISC(lbl_center_lon), 1.f, 0.5f);
+
+        /* default values for Top Left and Bottom Right are defined by the
+         * rectangle of the current and the previous Center */
+
+        /* Top Left. */
+        gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
+                label = gtk_label_new(_("Top-Left")),
+                0, 1, 3, 4, GTK_FILL, 0, 4, 0);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
+                mapman_info.txt_topleft_lat = gtk_entry_new(),
+                1, 2, 3, 4, GTK_FILL, 0, 4, 0);
+        gtk_entry_set_width_chars(GTK_ENTRY(mapman_info.txt_topleft_lat), 12);
+        gtk_entry_set_alignment(GTK_ENTRY(mapman_info.txt_topleft_lat), 1.f);
+        g_object_set(G_OBJECT(mapman_info.txt_topleft_lat),
+                HILDON_INPUT_MODE_HINT,
+                HILDON_INPUT_MODE_HINT_ALPHANUMERICSPECIAL, NULL);
+        gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
+                mapman_info.txt_topleft_lon = gtk_entry_new(),
+                2, 3, 3, 4, GTK_FILL, 0, 4, 0);
+        gtk_entry_set_width_chars(GTK_ENTRY(mapman_info.txt_topleft_lon), 12);
+        gtk_entry_set_alignment(GTK_ENTRY(mapman_info.txt_topleft_lon), 1.f);
+        g_object_set(G_OBJECT(mapman_info.txt_topleft_lon),
+                HILDON_INPUT_MODE_HINT,
+                HILDON_INPUT_MODE_HINT_ALPHANUMERICSPECIAL, NULL);
+
+        /* Bottom Right. */
+        gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
+                label = gtk_label_new(_("Bottom-Right")),
+                0, 1, 4, 5, GTK_FILL, 0, 4, 0);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
+                mapman_info.txt_botright_lat = gtk_entry_new(),
+                1, 2, 4, 5, GTK_FILL, 0, 4, 0);
+        gtk_entry_set_width_chars(GTK_ENTRY(mapman_info.txt_botright_lat), 12);
+        gtk_entry_set_alignment(GTK_ENTRY(mapman_info.txt_botright_lat), 1.f);
+        g_object_set(G_OBJECT(mapman_info.txt_botright_lat),
+                HILDON_INPUT_MODE_HINT,
+                HILDON_INPUT_MODE_HINT_ALPHANUMERICSPECIAL, NULL);
+        gtk_table_attach(GTK_TABLE(mapman_info.tbl_area),
+                mapman_info.txt_botright_lon = gtk_entry_new(),
+                2, 3, 4, 5, GTK_FILL, 0, 4, 0);
+        gtk_entry_set_width_chars(GTK_ENTRY(mapman_info.txt_botright_lat), 12);
+        gtk_entry_set_alignment(GTK_ENTRY(mapman_info.txt_botright_lon), 1.f);
+        g_object_set(G_OBJECT(mapman_info.txt_botright_lon),
+                HILDON_INPUT_MODE_HINT,
+                HILDON_INPUT_MODE_HINT_ALPHANUMERICSPECIAL, NULL);
+
+        /* Default action is to download by area. */
+        gtk_toggle_button_set_active(
+                GTK_TOGGLE_BUTTON(mapman_info.rad_by_area), TRUE);
+
+        g_signal_connect(G_OBJECT(mapman_info.rad_download), "clicked",
+                          G_CALLBACK(mapman_update_state), &mapman_info);
+        g_signal_connect(G_OBJECT(mapman_info.rad_delete), "clicked",
+                          G_CALLBACK(mapman_update_state), &mapman_info);
+        g_signal_connect(G_OBJECT(mapman_info.rad_by_area), "clicked",
+                          G_CALLBACK(mapman_update_state), &mapman_info);
+        g_signal_connect(G_OBJECT(mapman_info.rad_by_route), "clicked",
+                          G_CALLBACK(mapman_update_state), &mapman_info);
+    }
+
+    /* Initialize fields.  Do no use g_ascii_formatd; these strings will be
+     * output (and parsed) as locale-dependent. */
+
+    lat_format(_gps.lat, buffer);
+    gtk_label_set_text(GTK_LABEL(lbl_gps_lat), buffer);
+    lon_format(_gps.lon, buffer);
+    gtk_label_set_text(GTK_LABEL(lbl_gps_lon), buffer);
+
+    unit2latlon(_center.unitx, _center.unity, lat, lon);
+    lat_format(lat, buffer);
+    gtk_label_set_text(GTK_LABEL(lbl_center_lat), buffer);
+    lon_format(lon, buffer);
+    gtk_label_set_text(GTK_LABEL(lbl_center_lon), buffer);
+
+    /* Initialize to the bounds of the screen. */
+    unit2latlon(
+            _center.unitx - pixel2unit(MAX(_screen_width_pixels,
+                    _screen_height_pixels) / 2),
+            _center.unity - pixel2unit(MAX(_screen_width_pixels,
+                    _screen_height_pixels) / 2), lat, lon);
+    lat_format(lat, buffer);
+    gtk_entry_set_text(GTK_ENTRY(mapman_info.txt_topleft_lat), buffer);
+    lon_format(lon, buffer);
+    gtk_entry_set_text(GTK_ENTRY(mapman_info.txt_topleft_lon), buffer);
+
+    unit2latlon(
+            _center.unitx + pixel2unit(MAX(_screen_width_pixels,
+                    _screen_height_pixels) / 2),
+            _center.unity + pixel2unit(MAX(_screen_width_pixels,
+                    _screen_height_pixels) / 2), lat, lon);
+    lat_format(lat, buffer);
+    gtk_entry_set_text(GTK_ENTRY(mapman_info.txt_botright_lat), buffer);
+    lon_format(lon, buffer);
+    gtk_entry_set_text(GTK_ENTRY(mapman_info.txt_botright_lon), buffer);
+
+    gtk_toggle_button_set_active(
+            GTK_TOGGLE_BUTTON(mapman_info.chk_zoom_levels[
+                _zoom + (_curr_repo->double_size ? 1 : 0)]), TRUE);
+
+    gtk_widget_show_all(dialog);
+
+    mapman_update_state(NULL, &mapman_info);
+
+    if(_curr_repo->type != REPOTYPE_NONE)
+    {
+        gtk_widget_set_sensitive(mapman_info.rad_download, TRUE);
+    }
+    else
+    {
+        gtk_widget_set_sensitive(mapman_info.rad_download, FALSE);
+        popup_error(dialog,
+                _("NOTE: You must set a Map URI in the current repository in "
+                    "order to download maps."));
+    }
+
+    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
+    {
+        MapUpdateType update_type;
+        static gint download_batch_id = INT_MIN;
+
+        if(gtk_toggle_button_get_active(
+                    GTK_TOGGLE_BUTTON(mapman_info.rad_delete)))
+            update_type = MAP_UPDATE_DELETE;
+        else if(gtk_toggle_button_get_active(
+                GTK_TOGGLE_BUTTON(mapman_info.chk_overwrite)))
+            update_type = MAP_UPDATE_OVERWRITE;
+        else
+            update_type = MAP_UPDATE_ADD;
+
+        ++download_batch_id;
+        if(gtk_toggle_button_get_active(
+                    GTK_TOGGLE_BUTTON(mapman_info.rad_by_route)))
+        {
+            if(mapman_by_route(&mapman_info, update_type, download_batch_id))
+                break;
+        }
+        else
+        {
+            const gchar *text;
+            gchar *error_check;
+            gdouble start_lat, start_lon, end_lat, end_lon;
+
+            text = gtk_entry_get_text(GTK_ENTRY(mapman_info.txt_topleft_lat));
+            start_lat = strdmstod(text, &error_check);
+            if(text == error_check || start_lat < -90. || start_lat > 90.) {
+                popup_error(dialog, _("Invalid Top-Left Latitude"));
+                continue;
+            }
+
+            text = gtk_entry_get_text(GTK_ENTRY(mapman_info.txt_topleft_lon));
+            start_lon = strdmstod(text, &error_check);
+            if(text == error_check || start_lon < -180. || start_lon>180.) {
+                popup_error(dialog, _("Invalid Top-Left Longitude"));
+                continue;
+            }
+
+            text = gtk_entry_get_text(GTK_ENTRY(mapman_info.txt_botright_lat));
+            end_lat = strdmstod(text, &error_check);
+            if(text == error_check || end_lat < -90. || end_lat > 90.) {
+                popup_error(dialog, _("Invalid Bottom-Right Latitude"));
+                continue;
+            }
+
+            text = gtk_entry_get_text(GTK_ENTRY(mapman_info.txt_botright_lon));
+            end_lon = strdmstod(text, &error_check);
+            if(text == error_check || end_lon < -180. || end_lon > 180.) {
+                popup_error(dialog,_("Invalid Bottom-Right Longitude"));
+                continue;
+            }
+
+            if(mapman_by_area(start_lat, start_lon, end_lat, end_lon,
+                        &mapman_info, update_type, download_batch_id))
+                break;
+        }
+    }
+
+    gtk_widget_hide(dialog);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
diff --git a/src/maps.h b/src/maps.h
new file mode 100644 (file)
index 0000000..727c6cf
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAEMO_MAPPER_MAPS_H
+#define MAEMO_MAPPER_MAPS_H
+
+#include "defines.h"
+
+typedef struct _RepoManInfo RepoManInfo;
+struct _RepoManInfo {
+    GtkWidget *dialog;
+    GtkWidget *notebook;
+    GtkWidget *cmb_repos;
+    GList *repo_edits;
+};
+
+typedef struct _RepoEditInfo RepoEditInfo;
+struct _RepoEditInfo {
+    gchar *name;
+    GtkWidget *txt_url;
+    GtkWidget *txt_db_filename;
+    GtkWidget *num_dl_zoom_steps;
+    GtkWidget *num_view_zoom_steps;
+    GtkWidget *chk_double_size;
+    GtkWidget *chk_nextable;
+    GtkWidget *btn_browse;
+    BrowseInfo browse_info;
+};
+
+typedef struct _MapmanInfo MapmanInfo;
+struct _MapmanInfo {
+    GtkWidget *dialog;
+    GtkWidget *notebook;
+    GtkWidget *tbl_area;
+
+    /* The "Setup" tab. */
+    GtkWidget *rad_download;
+    GtkWidget *rad_delete;
+    GtkWidget *chk_overwrite;
+    GtkWidget *rad_by_area;
+    GtkWidget *rad_by_route;
+    GtkWidget *num_route_radius;
+
+    /* The "Area" tab. */
+    GtkWidget *txt_topleft_lat;
+    GtkWidget *txt_topleft_lon;
+    GtkWidget *txt_botright_lat;
+    GtkWidget *txt_botright_lon;
+
+    /* The "Zoom" tab. */
+    GtkWidget *chk_zoom_levels[MAX_ZOOM];
+};
+
+
+gboolean mapdb_exists(RepoData *repo, gint zoom, gint tilex, gint tiley,
+        gboolean should_lock);
+GdkPixbuf* mapdb_get(RepoData *repo, gint zoom, gint tilex, gint tiley);
+
+void set_repo_type(RepoData *repo);
+gboolean repo_set_curr(RepoData *rd);
+
+gboolean mapdb_initiate_update(RepoData *repo, gint zoom, gint tilex,
+        gint tiley, gint update_type, gint batch_id, gint priority,
+        ThreadLatch *refresh_latch);
+
+guint mut_exists_hashfunc(const MapUpdateTask *a);
+gboolean mut_exists_equalfunc(const MapUpdateTask *a, const MapUpdateTask *b);
+gint mut_priority_comparefunc(const MapUpdateTask *a, const MapUpdateTask *b);
+gboolean thread_proc_mut();
+
+gboolean repoman_dialog();
+
+gboolean mapman_dialog();
+
+#endif /* ifndef MAEMO_MAPPER_MAPS_H */
diff --git a/src/marshal.c b/src/marshal.c
new file mode 100644 (file)
index 0000000..5cf259f
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#define _GNU_SOURCE
+
+#include "marshal.h"
+
+#include    <glib-object.h>
+
+G_BEGIN_DECLS
+
+void
+g_cclosure_user_marshal_VOID__STRING_STRING_POINTER_UCHAR_UINT (GClosure     *closure,
+                                                                GValue       *return_value,
+                                                                guint         n_param_values,
+                                                                const GValue *param_values,
+                                                                gpointer      invocation_hint,
+                                                                gpointer      marshal_data)
+{
+  typedef void (*GMarshalFunc_VOID__STRING_STRING_POINTER_UCHAR_UINT) (gpointer     data1,
+                                                                       gpointer     arg_1,
+                                                                       gpointer     arg_2,
+                                                                       gpointer     arg_3,
+                                                                       guchar       arg_4,
+                                                                       guint        arg_5,
+                                                                       gpointer     data2);
+  register GMarshalFunc_VOID__STRING_STRING_POINTER_UCHAR_UINT callback;
+  register GCClosure *cc = (GCClosure*) closure;
+  register gpointer data1, data2;
+
+  g_return_if_fail (n_param_values == 6);
+
+  if (G_CCLOSURE_SWAP_DATA (closure))
+    {
+      data1 = closure->data;
+      data2 = g_value_peek_pointer (param_values + 0);
+    }
+  else
+    {
+      data1 = g_value_peek_pointer (param_values + 0);
+      data2 = closure->data;
+    }
+  callback = (GMarshalFunc_VOID__STRING_STRING_POINTER_UCHAR_UINT) (marshal_data ? marshal_data : cc->callback);
+
+  callback (data1,
+            g_marshal_value_peek_string (param_values + 1),
+            g_marshal_value_peek_string (param_values + 2),
+            g_marshal_value_peek_pointer (param_values + 3),
+            g_marshal_value_peek_uchar (param_values + 4),
+            g_marshal_value_peek_uint (param_values + 5),
+            data2);
+}
+
+G_END_DECLS
+
diff --git a/src/marshal.h b/src/marshal.h
new file mode 100644 (file)
index 0000000..ce798c4
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAEMO_MAPPER_MARSHAL_H
+#define MAEMO_MAPPER_MARSHAL_H
+
+#ifndef __g_cclosure_user_marshal_MARSHAL_H__
+#define __g_cclosure_user_marshal_MARSHAL_H__
+
+#include    <glib-object.h>
+
+G_BEGIN_DECLS
+
+#ifdef G_ENABLE_DEBUG
+#define g_marshal_value_peek_boolean(v)  g_value_get_boolean (v)
+#define g_marshal_value_peek_char(v)     g_value_get_char (v)
+#define g_marshal_value_peek_uchar(v)    g_value_get_uchar (v)
+#define g_marshal_value_peek_int(v)      g_value_get_int (v)
+#define g_marshal_value_peek_uint(v)     g_value_get_uint (v)
+#define g_marshal_value_peek_long(v)     g_value_get_long (v)
+#define g_marshal_value_peek_ulong(v)    g_value_get_ulong (v)
+#define g_marshal_value_peek_int64(v)    g_value_get_int64 (v)
+#define g_marshal_value_peek_uint64(v)   g_value_get_uint64 (v)
+#define g_marshal_value_peek_enum(v)     g_value_get_enum (v)
+#define g_marshal_value_peek_flags(v)    g_value_get_flags (v)
+#define g_marshal_value_peek_float(v)    g_value_get_float (v)
+#define g_marshal_value_peek_double(v)   g_value_get_double (v)
+#define g_marshal_value_peek_string(v)   (char*) g_value_get_string (v)
+#define g_marshal_value_peek_param(v)    g_value_get_param (v)
+#define g_marshal_value_peek_boxed(v)    g_value_get_boxed (v)
+#define g_marshal_value_peek_pointer(v)  g_value_get_pointer (v)
+#define g_marshal_value_peek_object(v)   g_value_get_object (v)
+#else /* !G_ENABLE_DEBUG */
+/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
+ *          Do not access GValues directly in your code. Instead, use the
+ *          g_value_get_*() functions
+ */
+#define g_marshal_value_peek_boolean(v)  (v)->data[0].v_int
+#define g_marshal_value_peek_char(v)     (v)->data[0].v_int
+#define g_marshal_value_peek_uchar(v)    (v)->data[0].v_uint
+#define g_marshal_value_peek_int(v)      (v)->data[0].v_int
+#define g_marshal_value_peek_uint(v)     (v)->data[0].v_uint
+#define g_marshal_value_peek_long(v)     (v)->data[0].v_long
+#define g_marshal_value_peek_ulong(v)    (v)->data[0].v_ulong
+#define g_marshal_value_peek_int64(v)    (v)->data[0].v_int64
+#define g_marshal_value_peek_uint64(v)   (v)->data[0].v_uint64
+#define g_marshal_value_peek_enum(v)     (v)->data[0].v_long
+#define g_marshal_value_peek_flags(v)    (v)->data[0].v_ulong
+#define g_marshal_value_peek_float(v)    (v)->data[0].v_float
+#define g_marshal_value_peek_double(v)   (v)->data[0].v_double
+#define g_marshal_value_peek_string(v)   (v)->data[0].v_pointer
+#define g_marshal_value_peek_param(v)    (v)->data[0].v_pointer
+#define g_marshal_value_peek_boxed(v)    (v)->data[0].v_pointer
+#define g_marshal_value_peek_pointer(v)  (v)->data[0].v_pointer
+#define g_marshal_value_peek_object(v)   (v)->data[0].v_pointer
+#endif /* !G_ENABLE_DEBUG */
+
+
+/* VOID:STRING,STRING,POINTER,UCHAR,UINT (marshal.list:1) */
+extern void g_cclosure_user_marshal_VOID__STRING_STRING_POINTER_UCHAR_UINT (GClosure     *closure,
+                                                                            GValue       *return_value,
+                                                                            guint         n_param_values,
+                                                                            const GValue *param_values,
+                                                                            gpointer      invocation_hint,
+                                                                            gpointer      marshal_data);
+
+G_END_DECLS
+
+#endif /* __g_cclosure_user_marshal_MARSHAL_H__ */
+
+
+#endif /* ifndef MAEMO_MAPPER_MARSHAL_H */
diff --git a/src/menu.c b/src/menu.c
new file mode 100644 (file)
index 0000000..77cbf48
--- /dev/null
@@ -0,0 +1,1745 @@
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define _GNU_SOURCE
+
+#include <math.h>
+#include <osso-helplib.h>
+#include <hildon-widgets/hildon-program.h>
+#include <hildon-widgets/hildon-banner.h>
+#include <hildon-widgets/hildon-input-mode-hint.h>
+
+#include "types.h"
+#include "data.h"
+#include "defines.h"
+
+#include "display.h"
+#include "gps.h"
+#include "gpx.h"
+#include "maps.h"
+#include "menu.h"
+#include "path.h"
+#include "poi.h"
+#include "settings.h"
+#include "util.h"
+
+static GtkWidget *_menu_route_open_item = NULL;
+static GtkWidget *_menu_route_download_item = NULL;
+static GtkWidget *_menu_route_save_item = NULL;
+static GtkWidget *_menu_route_distnext_item = NULL;
+static GtkWidget *_menu_route_distlast_item = NULL;
+static GtkWidget *_menu_route_reset_item = NULL;
+static GtkWidget *_menu_route_clear_item = NULL;
+static GtkWidget *_menu_track_open_item = NULL;
+static GtkWidget *_menu_track_save_item = NULL;
+static GtkWidget *_menu_track_insert_break_item = NULL;
+static GtkWidget *_menu_track_insert_mark_item = NULL;
+static GtkWidget *_menu_track_distlast_item = NULL;
+static GtkWidget *_menu_track_distfirst_item = NULL;
+static GtkWidget *_menu_track_clear_item = NULL;
+static GtkWidget *_menu_poi_import_item = NULL;
+static GtkWidget *_menu_poi_download_item = NULL;
+static GtkWidget *_menu_poi_browse_item = NULL;
+static GtkWidget *_menu_poi_categories_item = NULL;
+static GtkWidget *_menu_maps_submenu = NULL;
+static GtkWidget *_menu_maps_mapman_item = NULL;
+static GtkWidget *_menu_maps_repoman_item = NULL;
+static GtkWidget *_menu_view_zoom_in_item = NULL;
+static GtkWidget *_menu_view_zoom_out_item = NULL;
+static GtkWidget *_menu_view_rotate_clock_item = NULL;
+static GtkWidget *_menu_view_rotate_counter_item = NULL;
+static GtkWidget *_menu_view_rotate_reset_item = NULL;
+static GtkWidget *_menu_view_pan_up_item = NULL;
+static GtkWidget *_menu_view_pan_down_item = NULL;
+static GtkWidget *_menu_view_pan_left_item = NULL;
+static GtkWidget *_menu_view_pan_right_item = NULL;
+static GtkWidget *_menu_view_pan_north_item = NULL;
+static GtkWidget *_menu_view_pan_south_item = NULL;
+static GtkWidget *_menu_view_pan_west_item = NULL;
+static GtkWidget *_menu_view_pan_east_item = NULL;
+static GtkWidget *_menu_view_show_zoomlevel_item = NULL;
+static GtkWidget *_menu_view_show_comprose_item = NULL;
+static GtkWidget *_menu_view_show_velvec_item = NULL;
+static GtkWidget *_menu_view_goto_latlon_item = NULL;
+static GtkWidget *_menu_view_goto_address_item = NULL;
+static GtkWidget *_menu_view_goto_gps_item = NULL;
+static GtkWidget *_menu_view_goto_nextway_item = NULL;
+static GtkWidget *_menu_view_goto_nearpoi_item = NULL;
+static GtkWidget *_menu_settings_item = NULL;
+static GtkWidget *_menu_help_item = NULL;
+static GtkWidget *_menu_about_item = NULL;
+static GtkWidget *_menu_close_item = NULL;
+
+/****************************************************************************
+ * BELOW: ROUTE MENU ********************************************************
+ ****************************************************************************/
+
+static gboolean
+menu_cb_route_open(GtkMenuItem *item)
+{
+    gchar *buffer;
+    gint size;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(display_open_file(_window, &buffer, NULL, &size, &_route_dir_uri, NULL,
+                    GTK_FILE_CHOOSER_ACTION_OPEN))
+    {
+        /* If auto is enabled, append the route, otherwise replace it. */
+        if(gpx_path_parse(&_route, buffer, size,
+                    _autoroute_data.enabled ? 0 : 1))
+        {
+            path_save_route_to_db();
+
+            cancel_autoroute();
+
+            /* Find the nearest route point, if we're connected. */
+            route_find_nearest_point();
+
+            map_force_redraw();
+            MACRO_BANNER_SHOW_INFO(_window, _("Route Opened"));
+        }
+        else
+            popup_error(_window, _("Error parsing GPX file."));
+        g_free(buffer);
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_route_download(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+    route_download(NULL);
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_route_save(GtkMenuItem *item)
+{
+    GnomeVFSHandle *handle;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(display_open_file(_window, NULL, &handle, NULL, &_route_dir_uri, NULL,
+                    GTK_FILE_CHOOSER_ACTION_SAVE))
+    {
+        if(gpx_path_write(&_route, handle))
+        {
+            MACRO_BANNER_SHOW_INFO(_window, _("Route Saved"));
+        }
+        else
+            popup_error(_window, _("Error writing GPX file."));
+        gnome_vfs_close(handle);
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_route_distnext(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    route_show_distance_to_next();
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_route_distlast(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    route_show_distance_to_last();
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+gboolean
+menu_cb_route_reset(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    path_reset_route();
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_route_clear(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    cancel_autoroute();
+    MACRO_PATH_FREE(_route);
+    MACRO_PATH_INIT(_route);
+    path_save_route_to_db();
+    route_find_nearest_point();
+    map_force_redraw();
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+/****************************************************************************
+ * ABOVE: ROUTE MENU ********************************************************
+ ****************************************************************************/
+
+/****************************************************************************
+ * BELOW: TRACK MENU ********************************************************
+ ****************************************************************************/
+
+static gboolean
+menu_cb_track_open(GtkMenuItem *item)
+{
+    gchar *buffer;
+    gint size;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(display_open_file(_window, &buffer, NULL, &size, NULL, &_track_file_uri,
+                    GTK_FILE_CHOOSER_ACTION_OPEN))
+    {
+        if(gpx_path_parse(&_track, buffer, size, -1))
+        {
+            map_force_redraw();
+            MACRO_BANNER_SHOW_INFO(_window, _("Track Opened"));
+        }
+        else
+            popup_error(_window, _("Error parsing GPX file."));
+        g_free(buffer);
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_track_save(GtkMenuItem *item)
+{
+    GnomeVFSHandle *handle;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(display_open_file(_window, NULL, &handle, NULL, NULL, &_track_file_uri,
+                    GTK_FILE_CHOOSER_ACTION_SAVE))
+    {
+        if(gpx_path_write(&_track, handle))
+        {
+            MACRO_BANNER_SHOW_INFO(_window, _("Track Saved"));
+        }
+        else
+            popup_error(_window, _("Error writing GPX file."));
+        gnome_vfs_close(handle);
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_track_insert_break(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    track_insert_break(TRUE);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_track_insert_mark(GtkMenuItem *item)
+{
+    gfloat lat, lon;
+    gchar tmp1[LL_FMT_LEN], tmp2[LL_FMT_LEN], *p_latlon;
+    static GtkWidget *dialog = NULL;
+    static GtkWidget *table = NULL;
+    static GtkWidget *label = NULL;
+    static GtkWidget *lbl_latlon = NULL;
+    static GtkWidget *txt_scroll = NULL;
+    static GtkWidget *txt_desc = NULL;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(dialog == NULL)
+    {
+        dialog = gtk_dialog_new_with_buttons(_("Insert Mark"),
+                GTK_WINDOW(_window), GTK_DIALOG_MODAL,
+                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+                NULL);
+
+        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+                table = gtk_table_new(2, 2, FALSE), TRUE, TRUE, 0);
+
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Lat, Lon:")),
+                0, 1, 0, 1, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+
+        gtk_table_attach(GTK_TABLE(table),
+                lbl_latlon = gtk_label_new(""),
+                1, 2, 0, 1, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(lbl_latlon), 0.0f, 0.5f);
+
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Description")),
+                0, 1, 1, 2, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+
+        txt_scroll = gtk_scrolled_window_new(NULL, NULL);
+        gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(txt_scroll),
+                                       GTK_SHADOW_IN);
+        gtk_table_attach(GTK_TABLE(table),
+                txt_scroll,
+                1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+
+        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(txt_scroll),
+                GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+
+        txt_desc = gtk_text_view_new ();
+        gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt_desc), GTK_WRAP_WORD);
+
+        gtk_container_add(GTK_CONTAINER(txt_scroll), txt_desc);
+        gtk_widget_set_size_request(GTK_WIDGET(txt_scroll), 400, 60);
+    }
+
+    unit2latlon(_pos.unitx, _pos.unity, lat, lon);
+    lat_format(lat, tmp1);
+    lon_format(lon, tmp2);
+    p_latlon = g_strdup_printf("%s, %s", tmp1, tmp2);
+    gtk_label_set_text(GTK_LABEL(lbl_latlon), p_latlon);
+    g_free(p_latlon);
+
+    gtk_text_buffer_set_text(
+            gtk_text_view_get_buffer(GTK_TEXT_VIEW(txt_desc)), "", 0);
+
+    gtk_widget_show_all(dialog);
+
+    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
+    {
+        GtkTextBuffer *tbuf;
+        GtkTextIter ti1, ti2;
+        gchar *desc;
+
+        tbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txt_desc));
+        gtk_text_buffer_get_iter_at_offset(tbuf, &ti1, 0);
+        gtk_text_buffer_get_end_iter(tbuf, &ti2);
+        desc = gtk_text_buffer_get_text(tbuf, &ti1, &ti2, TRUE);
+
+        if(*desc)
+        {
+            MACRO_PATH_INCREMENT_WTAIL(_track);
+            _track.wtail->point = _track.tail;
+            _track.wtail->desc
+                = gtk_text_buffer_get_text(tbuf, &ti1, &ti2, TRUE);
+        }
+        else
+        {
+            popup_error(dialog,
+                    _("Please provide a description for the mark."));
+            g_free(desc);
+            continue;
+        }
+
+        map_render_paths();
+        MACRO_QUEUE_DRAW_AREA();
+        break;
+    }
+    gtk_widget_hide(dialog);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_track_distlast(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    track_show_distance_from_last();
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_track_distfirst(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    track_show_distance_from_first();
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_track_clear(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    track_clear();
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+/****************************************************************************
+ * ABOVE: TRACK MENU ********************************************************
+ ****************************************************************************/
+
+/****************************************************************************
+ * BELOW: POI MENU **********************************************************
+ ****************************************************************************/
+
+static gboolean
+menu_cb_poi_import(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(poi_import_dialog(_center.unitx, _center.unity))
+        map_force_redraw();
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_poi_download(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(poi_download_dialog(0, 0)) /* 0, 0 means no default origin */
+        map_force_redraw();
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_poi_browse(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(poi_browse_dialog(0, 0)) /* 0, 0 means no default origin */
+        map_force_redraw();
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_poi_categories(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(category_list_dialog())
+        map_force_redraw();
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+/****************************************************************************
+ * ABOVE: POI MENU **********************************************************
+ ****************************************************************************/
+
+/****************************************************************************
+ * BELOW: MAPS MENU *********************************************************
+ ****************************************************************************/
+
+static gboolean
+menu_cb_maps_repoman(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+    repoman_dialog();
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_maps_select(GtkMenuItem *item, gpointer new_repo)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item)))
+    {
+        repo_set_curr(new_repo);
+        map_refresh_mark(TRUE);
+    }
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_maps_mapman(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    mapman_dialog();
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_maps_auto_download(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if((_auto_download = gtk_check_menu_item_get_active(
+            GTK_CHECK_MENU_ITEM(_menu_maps_auto_download_item))))
+    {
+        if(_curr_repo->url == REPOTYPE_NONE)
+            popup_error(_window,
+                _("NOTE: You must set a Map URI in the current repository in "
+                    "order to download maps."));
+        map_refresh_mark(TRUE);
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+/****************************************************************************
+ * ABOVE: MAPS MENU *********************************************************
+ ****************************************************************************/
+
+/****************************************************************************
+ * BELOW: VIEW/ZOOM MENU ****************************************************
+ ****************************************************************************/
+
+static gboolean
+menu_cb_view_zoom_in(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(_zoom > MIN_ZOOM)
+    {
+        gchar buffer[80];
+        snprintf(buffer, sizeof(buffer),"%s %d",
+                _("Zoom to Level"), _next_zoom - 1);
+        MACRO_BANNER_SHOW_INFO(_window, buffer);
+        map_set_zoom(_next_zoom - 1);
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_view_zoom_out(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(_zoom < MAX_ZOOM - 1)
+    {
+        gchar buffer[80];
+        snprintf(buffer, sizeof(buffer),"%s %d",
+                _("Zoom to Level"), _next_zoom + 1);
+        MACRO_BANNER_SHOW_INFO(_window, buffer);
+        map_set_zoom(_next_zoom + 1);
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+/****************************************************************************
+ * ABOVE: VIEW/ZOOM MENU ****************************************************
+ ****************************************************************************/
+
+/****************************************************************************
+ * BELOW: VIEW/ROTATE MENU **************************************************
+ ****************************************************************************/
+
+static gboolean
+menu_cb_view_rotate_clock(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_view_rotate_counter(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_view_rotate_reset(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_view_rotate_auto(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(gtk_check_menu_item_get_active(
+                GTK_CHECK_MENU_ITEM(_menu_view_rotate_auto_item)))
+    {
+        _center_rotate = TRUE;
+        if(_center_mode > 0)
+            map_refresh_mark(TRUE);
+        MACRO_BANNER_SHOW_INFO(_window, _("Auto-Rotate Enabled"));
+    }
+    else
+    {
+        _center_rotate = FALSE;
+        MACRO_BANNER_SHOW_INFO(_window, _("Auto-Rotate Disabled"));
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+/****************************************************************************
+ * ABOVE: VIEW/ROTATE MENU **************************************************
+ ****************************************************************************/
+
+/****************************************************************************
+ * BELOW: VIEW/PAN MENU *****************************************************
+ ****************************************************************************/
+
+static gboolean
+menu_cb_view_pan_up(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_view_pan_down(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_view_pan_left(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_view_pan_right(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_view_pan_north(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_view_pan_south(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_view_pan_west(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_view_pan_east(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+/****************************************************************************
+ * ABOVE: VIEW/PAN MENU *****************************************************
+ ****************************************************************************/
+
+/****************************************************************************
+ * BELOW: VIEW/GOTO MENU ****************************************************
+ ****************************************************************************/
+
+static gboolean
+menu_cb_view_goto_latlon(GtkMenuItem *item)
+{
+    static GtkWidget *dialog = NULL;
+    static GtkWidget *table = NULL;
+    static GtkWidget *label = NULL;
+    static GtkWidget *txt_lat = NULL;
+    static GtkWidget *txt_lon = NULL;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(dialog == NULL)
+    {
+        dialog = gtk_dialog_new_with_buttons(_("Go to Lat/Lon"),
+                GTK_WINDOW(_window), GTK_DIALOG_MODAL,
+                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+                NULL);
+
+        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+                table = gtk_table_new(2, 3, FALSE), TRUE, TRUE, 0);
+
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Latitude")),
+                0, 1, 0, 1, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+
+        gtk_table_attach(GTK_TABLE(table),
+                txt_lat = gtk_entry_new(),
+                1, 2, 0, 1, GTK_FILL, 0, 2, 4);
+        gtk_entry_set_width_chars(GTK_ENTRY(txt_lat), 16);
+        gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+        g_object_set(G_OBJECT(txt_lat), HILDON_AUTOCAP, FALSE, NULL);
+        g_object_set(G_OBJECT(txt_lat), HILDON_INPUT_MODE_HINT,
+                HILDON_INPUT_MODE_HINT_ALPHANUMERICSPECIAL, NULL);
+
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Longitude")),
+                0, 1, 1, 2, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+
+        gtk_table_attach(GTK_TABLE(table),
+                txt_lon = gtk_entry_new(),
+                1, 2, 1, 2, GTK_FILL, 0, 2, 4);
+        gtk_entry_set_width_chars(GTK_ENTRY(txt_lon), 16);
+        gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+        g_object_set(G_OBJECT(txt_lon), HILDON_AUTOCAP, FALSE, NULL);
+        g_object_set(G_OBJECT(txt_lon), HILDON_INPUT_MODE_HINT,
+                HILDON_INPUT_MODE_HINT_ALPHANUMERICSPECIAL, NULL);
+    }
+
+    /* Initialize with the current center position. */
+    {
+        gchar buffer[32];
+        gfloat lat, lon;
+        unit2latlon(_center.unitx, _center.unity, lat, lon);
+        lat_format(lat, buffer);
+        gtk_entry_set_text(GTK_ENTRY(txt_lat), buffer);
+        lon_format(lon, buffer);
+        gtk_entry_set_text(GTK_ENTRY(txt_lon), buffer);
+    }
+
+    gtk_widget_show_all(dialog);
+
+    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
+    {
+        const gchar *text;
+        gchar *error_check;
+        gdouble lat, lon;
+        Point sel_unit;
+
+        text = gtk_entry_get_text(GTK_ENTRY(txt_lat));
+        lat = strdmstod(text, &error_check);
+        if(text == error_check || lat < -90. || lat > 90.) {
+            popup_error(dialog, _("Invalid Latitude"));
+            continue;
+        }
+
+        text = gtk_entry_get_text(GTK_ENTRY(txt_lon));
+        lon = strdmstod(text, &error_check);
+        if(text == error_check || lon < -180. || lon > 180.) {
+            popup_error(dialog, _("Invalid Longitude"));
+            continue;
+        }
+
+        latlon2unit(lat, lon, sel_unit.unitx, sel_unit.unity);
+        if(_center_mode > 0)
+            gtk_check_menu_item_set_active(
+                    GTK_CHECK_MENU_ITEM(_menu_view_ac_none_item), TRUE);
+        map_center_unit(sel_unit);
+        break;
+    }
+    gtk_widget_hide(dialog);
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_view_goto_address(GtkMenuItem *item)
+{
+    static GtkWidget *dialog = NULL;
+    static GtkWidget *table = NULL;
+    static GtkWidget *label = NULL;
+    static GtkWidget *txt_addr = NULL;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(dialog == NULL)
+    {
+        GtkEntryCompletion *comp;
+        dialog = gtk_dialog_new_with_buttons(_("Go to Address"),
+                GTK_WINDOW(_window), GTK_DIALOG_MODAL,
+                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+                NULL);
+
+        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+                table = gtk_table_new(2, 3, FALSE), TRUE, TRUE, 0);
+
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Address")),
+                0, 1, 0, 1, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+
+        gtk_table_attach(GTK_TABLE(table),
+                txt_addr = gtk_entry_new(),
+                1, 2, 0, 1, GTK_FILL, 0, 2, 4);
+        gtk_entry_set_width_chars(GTK_ENTRY(txt_addr), 25);
+        gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+
+        /* Set up auto-completion. */
+        comp = gtk_entry_completion_new();
+        gtk_entry_completion_set_model(comp, GTK_TREE_MODEL(_loc_model));
+        gtk_entry_completion_set_text_column(comp, 0);
+        gtk_entry_set_completion(GTK_ENTRY(txt_addr), comp);
+    }
+
+    gtk_widget_show_all(dialog);
+
+    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
+    {
+        Point origin = locate_address(dialog,
+                gtk_entry_get_text(GTK_ENTRY(txt_addr)));
+        if(origin.unity)
+        {
+            MACRO_BANNER_SHOW_INFO(_window, _("Address Located"));
+
+            if(_center_mode > 0)
+                gtk_check_menu_item_set_active(
+                        GTK_CHECK_MENU_ITEM(_menu_view_ac_none_item), TRUE);
+
+            map_center_unit(origin);
+
+            /* Success! Get out of the while loop. */
+            break;
+        }
+    }
+    gtk_widget_hide(dialog);
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_view_goto_gps(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(_center_mode > 0)
+        gtk_check_menu_item_set_active(
+                GTK_CHECK_MENU_ITEM(_menu_view_ac_none_item), TRUE);
+
+    map_center_unit(_pos);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+gboolean
+menu_cb_view_goto_nextway(GtkMenuItem *item)
+{
+    WayPoint *next_way;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    next_way = path_get_next_way();
+
+    if(next_way && next_way->point->unity)
+    {
+        if(_center_mode > 0)
+            gtk_check_menu_item_set_active(
+                    GTK_CHECK_MENU_ITEM(_menu_view_ac_none_item), TRUE);
+
+        map_center_unit(*next_way->point);
+    }
+    else
+    {
+        MACRO_BANNER_SHOW_INFO(_window, _("There is no next waypoint."));
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+gboolean
+menu_cb_view_goto_nearpoi(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(_poi_enabled)
+    {
+        PoiInfo poi;
+        gchar *banner;
+
+        if((_center_mode > 0 ? get_nearest_poi(_pos.unitx, _pos.unity, &poi)
+                    : get_nearest_poi(_center.unitx, _center.unity, &poi) ))
+        {
+            /* Auto-Center is enabled - use the GPS position. */
+            Point unit;
+            latlon2unit(poi.lat, poi.lon, unit.unitx, unit.unity);
+            banner = g_strdup_printf("%s (%s)", poi.label, poi.clabel);
+            MACRO_BANNER_SHOW_INFO(_window, banner);
+            g_free(banner);
+            g_free(poi.label);
+            g_free(poi.desc);
+            g_free(poi.clabel);
+
+            if(_center_mode > 0)
+                gtk_check_menu_item_set_active(
+                        GTK_CHECK_MENU_ITEM(_menu_view_ac_none_item), TRUE);
+
+            map_center_unit(unit);
+        }
+        else
+        {
+            MACRO_BANNER_SHOW_INFO(_window, _("No POIs found."));
+            /* Auto-Center is disabled - use the view center. */
+        }
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+/****************************************************************************
+ * ABOVE: VIEW/GOTO MENU ****************************************************
+ ****************************************************************************/
+
+/****************************************************************************
+ * BELOW: VIEW/SHOW MENU ****************************************************
+ ****************************************************************************/
+
+static gboolean
+menu_cb_view_show_tracks(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    _show_paths ^= TRACKS_MASK;
+    if(gtk_check_menu_item_get_active(
+                GTK_CHECK_MENU_ITEM(_menu_view_show_tracks_item)))
+    {
+        _show_paths |= TRACKS_MASK;
+        map_render_paths();
+        MACRO_QUEUE_DRAW_AREA();
+        MACRO_BANNER_SHOW_INFO(_window, _("Tracks are now shown"));
+    }
+    else
+    {
+        _show_paths &= ~TRACKS_MASK;
+        map_force_redraw();
+        MACRO_BANNER_SHOW_INFO(_window, _("Tracks are now hidden"));
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_view_show_zoomlevel(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    _show_zoomlevel = gtk_check_menu_item_get_active(
+                GTK_CHECK_MENU_ITEM(_menu_view_show_zoomlevel_item));
+    map_force_redraw();
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_view_show_scale(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    _show_scale = gtk_check_menu_item_get_active(
+                GTK_CHECK_MENU_ITEM(_menu_view_show_scale_item));
+    map_force_redraw();
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_view_show_comprose(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    _show_comprose = gtk_check_menu_item_get_active(
+                GTK_CHECK_MENU_ITEM(_menu_view_show_comprose_item));
+    map_force_redraw();
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_view_show_routes(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(gtk_check_menu_item_get_active(
+                GTK_CHECK_MENU_ITEM(_menu_view_show_routes_item)))
+    {
+        _show_paths |= ROUTES_MASK;
+        map_render_paths();
+        MACRO_QUEUE_DRAW_AREA();
+        MACRO_BANNER_SHOW_INFO(_window, _("Routes are now shown"));
+    }
+    else
+    {
+        _show_paths &= ~ROUTES_MASK;
+        map_force_redraw();
+        MACRO_BANNER_SHOW_INFO(_window, _("Routes are now hidden"));
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_view_show_velvec(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    _show_velvec = gtk_check_menu_item_get_active(
+            GTK_CHECK_MENU_ITEM(_menu_view_show_velvec_item));
+    map_move_mark();
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_view_show_poi(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    _show_poi = gtk_check_menu_item_get_active(
+            GTK_CHECK_MENU_ITEM(_menu_view_show_poi_item));
+    map_force_redraw();
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+/****************************************************************************
+ * ABOVE: VIEW/SHOW MENU ****************************************************
+ ****************************************************************************/
+
+/****************************************************************************
+ * BELOW: VIEW/AUTO-CENTER MENU *********************************************
+ ****************************************************************************/
+
+static gboolean
+menu_cb_view_ac_lead(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(_menu_view_ac_lead_item)))
+    {
+        _center_mode = CENTER_LEAD;
+        MACRO_BANNER_SHOW_INFO(_window, _("Auto-Center Mode: Lead"));
+        map_refresh_mark(TRUE);
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_view_ac_latlon(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(gtk_check_menu_item_get_active(
+                GTK_CHECK_MENU_ITEM(_menu_view_ac_latlon_item)))
+    {
+        _center_mode = CENTER_LATLON;
+        MACRO_BANNER_SHOW_INFO(_window, _("Auto-Center Mode: Lat/Lon"));
+        map_refresh_mark(TRUE);
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_view_ac_none(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(_menu_view_ac_none_item)))
+    {
+        _center_mode = -_center_mode;
+        MACRO_BANNER_SHOW_INFO(_window, _("Auto-Center Off"));
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+/****************************************************************************
+ * ABOVE: VIEW/AUTO-CENTER MENU *********************************************
+ ****************************************************************************/
+
+static gboolean
+menu_cb_view_fullscreen(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if((_fullscreen = gtk_check_menu_item_get_active(
+                GTK_CHECK_MENU_ITEM(_menu_view_fullscreen_item))))
+        gtk_window_fullscreen(GTK_WINDOW(_window));
+    else
+        gtk_window_unfullscreen(GTK_WINDOW(_window));
+
+    g_idle_add((GSourceFunc)window_present, NULL);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+/****************************************************************************
+ * BELOW: GPS MENU **********************************************************
+ ****************************************************************************/
+
+static gboolean
+menu_cb_enable_gps(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if((_enable_gps = gtk_check_menu_item_get_active(
+                GTK_CHECK_MENU_ITEM(_menu_enable_gps_item))))
+    {
+        if(_gri.type != GPS_RCVR_NONE)
+        {
+            rcvr_connect();
+        }
+        else
+        {
+            popup_error(_window,
+                    _("Cannot enable GPS until a GPS receiver "
+                    "is set up in the Settings dialog box."));
+            gtk_check_menu_item_set_active(
+                    GTK_CHECK_MENU_ITEM(_menu_enable_gps_item), FALSE);
+        }
+    }
+    else
+    {
+        rcvr_disconnect();
+    }
+    map_move_mark();
+    gps_show_info();
+    gtk_widget_set_sensitive(GTK_WIDGET(_menu_gps_details_item), _enable_gps);
+    gtk_widget_set_sensitive(GTK_WIDGET(_menu_gps_reset_item), _enable_gps);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_gps_show_info(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    _gps_info = gtk_check_menu_item_get_active(
+                GTK_CHECK_MENU_ITEM(_menu_gps_show_info_item));
+
+    gps_show_info();
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_gps_details(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    gps_details();
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_gps_reset(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    reset_bluetooth();
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+/****************************************************************************
+ * ABOVE: GPS MENU **********************************************************
+ ****************************************************************************/
+
+static gboolean
+menu_cb_settings(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(settings_dialog())
+    {
+        /* Settings have changed - reconnect to receiver. */
+        if(_enable_gps)
+        {
+            rcvr_disconnect();
+            rcvr_connect();
+        }
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_help(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    ossohelp_show(_osso, HELP_ID_INTRO, 0);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+menu_cb_about(GtkMenuItem *item)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    ossohelp_show(_osso, HELP_ID_ABOUT, OSSO_HELP_SHOW_DIALOG);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+
+
+void
+menu_maps_remove_repos()
+{
+    GList *curr;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    /* Delete one menu item for each repo. */
+    for(curr = _repo_list; curr; curr = curr->next)
+    {
+        gtk_widget_destroy(gtk_container_get_children(
+                    GTK_CONTAINER(_menu_maps_submenu))->data);
+    }
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+void
+menu_maps_add_repos()
+{
+    GList *curr;
+    GtkWidget *last_repo = NULL;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    for(curr = g_list_last(_repo_list); curr; curr = curr->prev)
+    {
+        RepoData *rd = (RepoData*)curr->data;
+        GtkWidget *menu_item;
+        if(last_repo)
+            gtk_menu_prepend(_menu_maps_submenu, menu_item
+                    = gtk_radio_menu_item_new_with_label_from_widget(
+                        GTK_RADIO_MENU_ITEM(last_repo), rd->name));
+        else
+        {
+            gtk_menu_prepend(_menu_maps_submenu, menu_item
+                    = gtk_radio_menu_item_new_with_label(NULL, rd->name));
+            last_repo = menu_item;
+        }
+        gtk_check_menu_item_set_active(
+                GTK_CHECK_MENU_ITEM(menu_item), rd == _curr_repo);
+        rd->menu_item = menu_item;
+    }
+
+    /* Add signals (must be after entire menu is built). */
+    {
+        GList *currmi = gtk_container_get_children(
+                GTK_CONTAINER(_menu_maps_submenu));
+        for(curr = _repo_list; curr; curr = curr->next, currmi = currmi->next)
+        {
+            g_signal_connect(G_OBJECT(currmi->data), "activate",
+                             G_CALLBACK(menu_cb_maps_select), curr->data);
+        }
+    }
+
+    gtk_widget_show_all(_menu_maps_submenu);
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+/**
+ * Create the menu items needed for the drop down menu.
+ */
+void
+menu_init()
+{
+    /* Create needed handles. */
+    GtkMenu *menu;
+    GtkWidget *submenu;
+    GtkWidget *submenu2;
+    GtkWidget *menu_item;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    /* Get the menu of our view. */
+    menu = GTK_MENU(gtk_menu_new());
+
+    /* Create the menu items. */
+
+    /* The "Routes" submenu. */
+    gtk_menu_append(menu, menu_item
+            = gtk_menu_item_new_with_label(_("Route")));
+    gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
+            submenu = gtk_menu_new());
+    gtk_menu_append(submenu, _menu_route_open_item
+            = gtk_menu_item_new_with_label(_("Open...")));
+    gtk_menu_append(submenu, _menu_route_download_item
+            = gtk_menu_item_new_with_label(_("Download...")));
+    gtk_menu_append(submenu, _menu_route_save_item
+            = gtk_menu_item_new_with_label(_("Save...")));
+    gtk_menu_append(submenu, _menu_route_distnext_item
+        = gtk_menu_item_new_with_label(_("Show Distance to Next Waypoint")));
+    gtk_menu_append(submenu, _menu_route_distlast_item
+        = gtk_menu_item_new_with_label(_("Show Distance to End of Route")));
+    gtk_menu_append(submenu, _menu_route_reset_item
+            = gtk_menu_item_new_with_label(_("Reset")));
+    gtk_menu_append(submenu, _menu_route_clear_item
+            = gtk_menu_item_new_with_label(_("Clear")));
+
+    /* The "Track" submenu. */
+    gtk_menu_append(menu, menu_item
+            = gtk_menu_item_new_with_label(_("Track")));
+    gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
+            submenu = gtk_menu_new());
+    gtk_menu_append(submenu, _menu_track_open_item
+            = gtk_menu_item_new_with_label(_("Open...")));
+    gtk_menu_append(submenu, _menu_track_save_item
+            = gtk_menu_item_new_with_label(_("Save...")));
+    gtk_menu_append(submenu, _menu_track_insert_break_item
+            = gtk_menu_item_new_with_label(_("Insert Break")));
+    gtk_menu_append(submenu, _menu_track_insert_mark_item
+            = gtk_menu_item_new_with_label(_("Insert Mark...")));
+    gtk_menu_append(submenu, _menu_track_distlast_item
+            = gtk_menu_item_new_with_label(_("Show Distance from Last Mark")));
+    gtk_menu_append(submenu, _menu_track_distfirst_item
+            = gtk_menu_item_new_with_label(_("Show Distance from Beginning")));
+    gtk_menu_append(submenu, _menu_track_clear_item
+            = gtk_menu_item_new_with_label(_("Clear")));
+
+    /* The "POI" submenu. */
+    gtk_menu_append(menu, menu_item = _menu_poi_item
+            = gtk_menu_item_new_with_label(_("POI")));
+    gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
+            submenu = gtk_menu_new());
+    gtk_menu_append(submenu, _menu_poi_import_item
+            = gtk_menu_item_new_with_label(_("Import...")));
+    gtk_menu_append(submenu, _menu_poi_download_item
+            = gtk_menu_item_new_with_label(_("Download...")));
+    gtk_menu_append(submenu, _menu_poi_browse_item
+            = gtk_menu_item_new_with_label(_("Browse...")));
+    gtk_menu_append(submenu, _menu_poi_categories_item
+            = gtk_menu_item_new_with_label(_("Categories...")));
+
+    /* The "Maps" submenu. */
+    gtk_menu_append(menu, menu_item
+            = gtk_menu_item_new_with_label(_("Maps")));
+    gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
+            _menu_maps_submenu = gtk_menu_new());
+    gtk_menu_append(_menu_maps_submenu, gtk_separator_menu_item_new());
+    gtk_menu_append(_menu_maps_submenu, _menu_maps_mapman_item
+            = gtk_menu_item_new_with_label(_("Manage Maps...")));
+    gtk_menu_append(_menu_maps_submenu, _menu_maps_repoman_item
+            = gtk_menu_item_new_with_label(_("Manage Repositories...")));
+    gtk_menu_append(_menu_maps_submenu, _menu_maps_auto_download_item
+            = gtk_check_menu_item_new_with_label(_("Auto-Download")));
+    gtk_check_menu_item_set_active(
+            GTK_CHECK_MENU_ITEM(_menu_maps_auto_download_item),_auto_download);
+    menu_maps_add_repos(_curr_repo);
+
+    gtk_menu_append(menu, gtk_separator_menu_item_new());
+
+    /* The "View" submenu. */
+    gtk_menu_append(menu, menu_item
+            = gtk_menu_item_new_with_label(_("View")));
+    gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
+            submenu = gtk_menu_new());
+
+    /* The "View"/"Zoom" submenu. */
+    gtk_menu_append(submenu, menu_item
+            = gtk_menu_item_new_with_label(_("Zoom")));
+    gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
+            submenu2 = gtk_menu_new());
+    gtk_menu_append(submenu2, _menu_view_zoom_in_item
+            = gtk_menu_item_new_with_label(_("Zoom In")));
+    gtk_menu_append(submenu2, _menu_view_zoom_out_item
+            = gtk_menu_item_new_with_label(_("Zoom Out")));
+
+    /* The "View"/"Rotate" submenu. */
+    gtk_menu_append(submenu, menu_item
+            = gtk_menu_item_new_with_label(_("Rotate")));
+    gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
+            submenu2 = gtk_menu_new());
+    gtk_menu_append(submenu2, _menu_view_rotate_clock_item
+            = gtk_menu_item_new_with_label(_("Clockwise")));
+    gtk_menu_append(submenu2, _menu_view_rotate_counter_item
+            = gtk_menu_item_new_with_label(_("Counter")));
+    gtk_menu_append(submenu2, _menu_view_rotate_reset_item
+            = gtk_menu_item_new_with_label(_("Reset")));
+    gtk_menu_append(submenu2, _menu_view_rotate_auto_item
+            = gtk_check_menu_item_new_with_label(_("Auto-Rotate")));
+    gtk_check_menu_item_set_active(
+            GTK_CHECK_MENU_ITEM(_menu_view_rotate_auto_item), _center_rotate);
+
+    /* The "View"/"Pan" submenu. */
+    gtk_menu_append(submenu, menu_item
+            = gtk_menu_item_new_with_label(_("Pan")));
+    gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
+            submenu2 = gtk_menu_new());
+    gtk_menu_append(submenu2, _menu_view_pan_up_item
+            = gtk_menu_item_new_with_label(_("Up")));
+    gtk_menu_append(submenu2, _menu_view_pan_down_item
+            = gtk_menu_item_new_with_label(_("Down")));
+    gtk_menu_append(submenu2, _menu_view_pan_left_item
+            = gtk_menu_item_new_with_label(_("Left")));
+    gtk_menu_append(submenu2, _menu_view_pan_right_item
+            = gtk_menu_item_new_with_label(_("Right")));
+    gtk_menu_append(submenu2, gtk_separator_menu_item_new());
+    gtk_menu_append(submenu2, _menu_view_pan_north_item
+            = gtk_menu_item_new_with_label(_("North")));
+    gtk_menu_append(submenu2, _menu_view_pan_south_item
+            = gtk_menu_item_new_with_label(_("South")));
+    gtk_menu_append(submenu2, _menu_view_pan_west_item
+            = gtk_menu_item_new_with_label(_("West")));
+    gtk_menu_append(submenu2, _menu_view_pan_east_item
+            = gtk_menu_item_new_with_label(_("East")));
+
+    /* The "Go to" submenu. */
+    gtk_menu_append(submenu, menu_item
+            = gtk_menu_item_new_with_label(_("Go to")));
+    gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
+            submenu2 = gtk_menu_new());
+    gtk_menu_append(submenu2, _menu_view_goto_latlon_item
+            = gtk_menu_item_new_with_label(_("Lat/Lon...")));
+    gtk_menu_append(submenu2, _menu_view_goto_address_item
+            = gtk_menu_item_new_with_label(_("Address...")));
+    gtk_menu_append(submenu2, _menu_view_goto_gps_item
+            = gtk_menu_item_new_with_label(_("GPS Location")));
+    gtk_menu_append(submenu2, _menu_view_goto_nextway_item
+            = gtk_menu_item_new_with_label(_("Next Waypoint")));
+    gtk_menu_append(submenu2, _menu_view_goto_nearpoi_item
+            = gtk_menu_item_new_with_label(_("Nearest POI")));
+
+    gtk_menu_append(submenu, gtk_separator_menu_item_new());
+
+    /* The "View"/"Show" submenu. */
+    gtk_menu_append(submenu, menu_item
+            = gtk_menu_item_new_with_label(_("Show")));
+    gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
+            submenu2 = gtk_menu_new());
+    gtk_menu_append(submenu2, _menu_view_show_zoomlevel_item
+            = gtk_check_menu_item_new_with_label(_("Zoom Level")));
+    gtk_check_menu_item_set_active(
+            GTK_CHECK_MENU_ITEM(_menu_view_show_zoomlevel_item),
+            _show_zoomlevel);
+    gtk_menu_append(submenu2, _menu_view_show_scale_item
+            = gtk_check_menu_item_new_with_label(_("Scale")));
+    gtk_check_menu_item_set_active(
+            GTK_CHECK_MENU_ITEM(_menu_view_show_scale_item),
+            _show_scale);
+    gtk_menu_append(submenu2, _menu_view_show_comprose_item
+            = gtk_check_menu_item_new_with_label(_("Compass Rose")));
+    gtk_check_menu_item_set_active(
+            GTK_CHECK_MENU_ITEM(_menu_view_show_comprose_item),
+            _show_comprose);
+    gtk_menu_append(submenu2, _menu_view_show_routes_item
+            = gtk_check_menu_item_new_with_label(_("Route")));
+    gtk_check_menu_item_set_active(
+            GTK_CHECK_MENU_ITEM(_menu_view_show_routes_item),
+            _show_paths & ROUTES_MASK);
+    gtk_menu_append(submenu2, _menu_view_show_tracks_item
+            = gtk_check_menu_item_new_with_label(_("Track")));
+    gtk_check_menu_item_set_active(
+            GTK_CHECK_MENU_ITEM(_menu_view_show_tracks_item),
+            _show_paths & TRACKS_MASK);
+    gtk_menu_append(submenu2, _menu_view_show_velvec_item
+            = gtk_check_menu_item_new_with_label(_("Velocity Vector")));
+    gtk_check_menu_item_set_active(
+            GTK_CHECK_MENU_ITEM(_menu_view_show_velvec_item), _show_velvec);
+    gtk_menu_append(submenu2, _menu_view_show_poi_item
+            = gtk_check_menu_item_new_with_label(_("POI")));
+    gtk_check_menu_item_set_active(
+            GTK_CHECK_MENU_ITEM(_menu_view_show_poi_item), _show_poi);
+
+    /* The "View"/"Auto-Center" submenu. */
+    gtk_menu_append(submenu, menu_item
+            = gtk_menu_item_new_with_label(_("Auto-Center")));
+    gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
+            submenu2 = gtk_menu_new());
+    gtk_menu_append(submenu2, _menu_view_ac_latlon_item
+            = gtk_radio_menu_item_new_with_label(NULL, _("Lat/Lon")));
+    gtk_check_menu_item_set_active(
+            GTK_CHECK_MENU_ITEM(_menu_view_ac_latlon_item),
+            _center_mode == CENTER_LATLON);
+    gtk_menu_append(submenu2, _menu_view_ac_lead_item
+            = gtk_radio_menu_item_new_with_label_from_widget(
+                GTK_RADIO_MENU_ITEM(_menu_view_ac_latlon_item), _("Lead")));
+    gtk_check_menu_item_set_active(
+            GTK_CHECK_MENU_ITEM(_menu_view_ac_lead_item),
+            _center_mode == CENTER_LEAD);
+    gtk_menu_append(submenu2, _menu_view_ac_none_item
+            = gtk_radio_menu_item_new_with_label_from_widget(
+                GTK_RADIO_MENU_ITEM(_menu_view_ac_latlon_item), _("None")));
+    gtk_check_menu_item_set_active(
+            GTK_CHECK_MENU_ITEM(_menu_view_ac_none_item),
+            _center_mode < 0);
+
+    gtk_menu_append(submenu, gtk_separator_menu_item_new());
+
+    gtk_menu_append(submenu, _menu_view_fullscreen_item
+            = gtk_check_menu_item_new_with_label(_("Full Screen")));
+    gtk_check_menu_item_set_active(
+            GTK_CHECK_MENU_ITEM(_menu_view_fullscreen_item), _fullscreen);
+
+    /* The "GPS" submenu. */
+    gtk_menu_append(menu, menu_item
+            = gtk_menu_item_new_with_label(_("GPS")));
+    gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
+            submenu = gtk_menu_new());
+    gtk_menu_append(submenu, _menu_enable_gps_item
+            = gtk_check_menu_item_new_with_label(_("Enable GPS")));
+    gtk_check_menu_item_set_active(
+            GTK_CHECK_MENU_ITEM(_menu_enable_gps_item), _enable_gps);
+    gtk_menu_append(submenu, _menu_gps_show_info_item
+            = gtk_check_menu_item_new_with_label(_("Show Information")));
+    gtk_check_menu_item_set_active(
+            GTK_CHECK_MENU_ITEM(_menu_gps_show_info_item), _gps_info);
+    gtk_menu_append(submenu, _menu_gps_details_item
+            = gtk_menu_item_new_with_label(_("Details...")));
+    gtk_widget_set_sensitive(GTK_WIDGET(_menu_gps_details_item), _enable_gps);
+    gtk_menu_append(submenu, _menu_gps_reset_item
+        = gtk_menu_item_new_with_label(_("Reset Bluetooth")));
+    gtk_widget_set_sensitive(GTK_WIDGET(_menu_gps_reset_item), _enable_gps);
+
+    gtk_menu_append(menu, gtk_separator_menu_item_new());
+
+    /* The other menu items. */
+    gtk_menu_append(menu, _menu_settings_item
+        = gtk_menu_item_new_with_label(_("Settings...")));
+    gtk_menu_append(menu, gtk_separator_menu_item_new());
+    gtk_menu_append(menu, _menu_help_item
+        = gtk_menu_item_new_with_label(_("Help...")));
+    gtk_menu_append(menu, _menu_about_item
+        = gtk_menu_item_new_with_label(_("About...")));
+    gtk_menu_append(menu, _menu_close_item
+        = gtk_menu_item_new_with_label(_("Close")));
+
+    /* We need to show menu items. */
+    gtk_widget_show_all(GTK_WIDGET(menu));
+
+    hildon_window_set_menu(HILDON_WINDOW(_window), menu);
+
+    /* Connect the "Route" signals. */
+    g_signal_connect(G_OBJECT(_menu_route_open_item), "activate",
+                      G_CALLBACK(menu_cb_route_open), NULL);
+    g_signal_connect(G_OBJECT(_menu_route_download_item), "activate",
+                      G_CALLBACK(menu_cb_route_download), NULL);
+    g_signal_connect(G_OBJECT(_menu_route_save_item), "activate",
+                      G_CALLBACK(menu_cb_route_save), NULL);
+    g_signal_connect(G_OBJECT(_menu_route_distnext_item), "activate",
+                      G_CALLBACK(menu_cb_route_distnext), NULL);
+    g_signal_connect(G_OBJECT(_menu_route_distlast_item), "activate",
+                      G_CALLBACK(menu_cb_route_distlast), NULL);
+    g_signal_connect(G_OBJECT(_menu_route_reset_item), "activate",
+                      G_CALLBACK(menu_cb_route_reset), NULL);
+    g_signal_connect(G_OBJECT(_menu_route_clear_item), "activate",
+                      G_CALLBACK(menu_cb_route_clear), NULL);
+
+    /* Connect the "Track" signals. */
+    g_signal_connect(G_OBJECT(_menu_track_open_item), "activate",
+                      G_CALLBACK(menu_cb_track_open), NULL);
+    g_signal_connect(G_OBJECT(_menu_track_save_item), "activate",
+                      G_CALLBACK(menu_cb_track_save), NULL);
+    g_signal_connect(G_OBJECT(_menu_track_insert_break_item), "activate",
+                      G_CALLBACK(menu_cb_track_insert_break), NULL);
+    g_signal_connect(G_OBJECT(_menu_track_insert_mark_item), "activate",
+                      G_CALLBACK(menu_cb_track_insert_mark), NULL);
+    g_signal_connect(G_OBJECT(_menu_track_distlast_item), "activate",
+                      G_CALLBACK(menu_cb_track_distlast), NULL);
+    g_signal_connect(G_OBJECT(_menu_track_distfirst_item), "activate",
+                      G_CALLBACK(menu_cb_track_distfirst), NULL);
+    g_signal_connect(G_OBJECT(_menu_track_clear_item), "activate",
+                      G_CALLBACK(menu_cb_track_clear), NULL);
+
+    /* Connect the "POI" signals. */
+    g_signal_connect(G_OBJECT(_menu_poi_import_item), "activate",
+                      G_CALLBACK(menu_cb_poi_import), NULL);
+    g_signal_connect(G_OBJECT(_menu_poi_download_item), "activate",
+                      G_CALLBACK(menu_cb_poi_download), NULL);
+    g_signal_connect(G_OBJECT(_menu_poi_browse_item), "activate",
+                      G_CALLBACK(menu_cb_poi_browse), NULL);
+    g_signal_connect(G_OBJECT(_menu_poi_categories_item), "activate",
+                      G_CALLBACK(menu_cb_poi_categories), NULL);
+
+    /* Connect the "Maps" signals. */
+    g_signal_connect(G_OBJECT(_menu_maps_repoman_item), "activate",
+                      G_CALLBACK(menu_cb_maps_repoman), NULL);
+    g_signal_connect(G_OBJECT(_menu_maps_mapman_item), "activate",
+                      G_CALLBACK(menu_cb_maps_mapman), NULL);
+    g_signal_connect(G_OBJECT(_menu_maps_auto_download_item), "toggled",
+                      G_CALLBACK(menu_cb_maps_auto_download), NULL);
+
+    /* Connect the "View" signals. */
+    g_signal_connect(G_OBJECT(_menu_view_zoom_in_item), "activate",
+                      G_CALLBACK(menu_cb_view_zoom_in), NULL);
+    g_signal_connect(G_OBJECT(_menu_view_zoom_out_item), "activate",
+                      G_CALLBACK(menu_cb_view_zoom_out), NULL);
+
+    g_signal_connect(G_OBJECT(_menu_view_rotate_clock_item), "activate",
+                      G_CALLBACK(menu_cb_view_rotate_clock), NULL);
+    g_signal_connect(G_OBJECT(_menu_view_rotate_counter_item), "activate",
+                      G_CALLBACK(menu_cb_view_rotate_counter), NULL);
+    g_signal_connect(G_OBJECT(_menu_view_rotate_reset_item), "activate",
+                      G_CALLBACK(menu_cb_view_rotate_reset), NULL);
+    g_signal_connect(G_OBJECT(_menu_view_rotate_auto_item), "toggled",
+                      G_CALLBACK(menu_cb_view_rotate_auto), NULL);
+
+    g_signal_connect(G_OBJECT(_menu_view_pan_up_item), "activate",
+                      G_CALLBACK(menu_cb_view_pan_up), NULL);
+    g_signal_connect(G_OBJECT(_menu_view_pan_down_item), "activate",
+                      G_CALLBACK(menu_cb_view_pan_down), NULL);
+    g_signal_connect(G_OBJECT(_menu_view_pan_left_item), "activate",
+                      G_CALLBACK(menu_cb_view_pan_left), NULL);
+    g_signal_connect(G_OBJECT(_menu_view_pan_right_item), "activate",
+                      G_CALLBACK(menu_cb_view_pan_right), NULL);
+    g_signal_connect(G_OBJECT(_menu_view_pan_north_item), "activate",
+                      G_CALLBACK(menu_cb_view_pan_north), NULL);
+    g_signal_connect(G_OBJECT(_menu_view_pan_south_item), "activate",
+                      G_CALLBACK(menu_cb_view_pan_south), NULL);
+    g_signal_connect(G_OBJECT(_menu_view_pan_west_item), "activate",
+                      G_CALLBACK(menu_cb_view_pan_west), NULL);
+    g_signal_connect(G_OBJECT(_menu_view_pan_east_item), "activate",
+                      G_CALLBACK(menu_cb_view_pan_east), NULL);
+
+    g_signal_connect(G_OBJECT(_menu_view_goto_latlon_item), "activate",
+                      G_CALLBACK(menu_cb_view_goto_latlon), NULL);
+    g_signal_connect(G_OBJECT(_menu_view_goto_address_item), "activate",
+                      G_CALLBACK(menu_cb_view_goto_address), NULL);
+    g_signal_connect(G_OBJECT(_menu_view_goto_gps_item), "activate",
+                      G_CALLBACK(menu_cb_view_goto_gps), NULL);
+    g_signal_connect(G_OBJECT(_menu_view_goto_nextway_item), "activate",
+                      G_CALLBACK(menu_cb_view_goto_nextway), NULL);
+    g_signal_connect(G_OBJECT(_menu_view_goto_nearpoi_item), "activate",
+                      G_CALLBACK(menu_cb_view_goto_nearpoi), NULL);
+
+    g_signal_connect(G_OBJECT(_menu_view_show_tracks_item), "toggled",
+                      G_CALLBACK(menu_cb_view_show_tracks), NULL);
+    g_signal_connect(G_OBJECT(_menu_view_show_zoomlevel_item), "toggled",
+                      G_CALLBACK(menu_cb_view_show_zoomlevel), NULL);
+    g_signal_connect(G_OBJECT(_menu_view_show_scale_item), "toggled",
+                      G_CALLBACK(menu_cb_view_show_scale), NULL);
+    g_signal_connect(G_OBJECT(_menu_view_show_comprose_item), "toggled",
+                      G_CALLBACK(menu_cb_view_show_comprose), NULL);
+    g_signal_connect(G_OBJECT(_menu_view_show_routes_item), "toggled",
+                      G_CALLBACK(menu_cb_view_show_routes), NULL);
+    g_signal_connect(G_OBJECT(_menu_view_show_velvec_item), "toggled",
+                      G_CALLBACK(menu_cb_view_show_velvec), NULL);
+    g_signal_connect(G_OBJECT(_menu_view_show_poi_item), "toggled",
+                      G_CALLBACK(menu_cb_view_show_poi), NULL);
+
+    g_signal_connect(G_OBJECT(_menu_view_ac_latlon_item), "toggled",
+                      G_CALLBACK(menu_cb_view_ac_latlon), NULL);
+    g_signal_connect(G_OBJECT(_menu_view_ac_lead_item), "toggled",
+                      G_CALLBACK(menu_cb_view_ac_lead), NULL);
+    g_signal_connect(G_OBJECT(_menu_view_ac_none_item), "toggled",
+                      G_CALLBACK(menu_cb_view_ac_none), NULL);
+
+    g_signal_connect(G_OBJECT(_menu_view_fullscreen_item), "toggled",
+                      G_CALLBACK(menu_cb_view_fullscreen), NULL);
+
+    /* Connect the "GPS" signals. */
+    g_signal_connect(G_OBJECT(_menu_enable_gps_item), "toggled",
+                      G_CALLBACK(menu_cb_enable_gps), NULL);
+    g_signal_connect(G_OBJECT(_menu_gps_show_info_item), "toggled",
+                      G_CALLBACK(menu_cb_gps_show_info), NULL);
+    g_signal_connect(G_OBJECT(_menu_gps_details_item), "activate",
+                      G_CALLBACK(menu_cb_gps_details), NULL);
+    g_signal_connect(G_OBJECT(_menu_gps_reset_item), "activate",
+                      G_CALLBACK(menu_cb_gps_reset), NULL);
+
+    /* Connect the other menu item signals. */
+    g_signal_connect(G_OBJECT(_menu_settings_item), "activate",
+                      G_CALLBACK(menu_cb_settings), NULL);
+    g_signal_connect(G_OBJECT(_menu_help_item), "activate",
+                      G_CALLBACK(menu_cb_help), NULL);
+    g_signal_connect(G_OBJECT(_menu_about_item), "activate",
+                      G_CALLBACK(menu_cb_about), NULL);
+    g_signal_connect(G_OBJECT(_menu_close_item), "activate",
+                      G_CALLBACK(gtk_main_quit), NULL);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
diff --git a/src/menu.h b/src/menu.h
new file mode 100644 (file)
index 0000000..32ba208
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAEMO_MAPPER_MENU_H
+#define MAEMO_MAPPER_MENU_H
+
+gboolean menu_cb_view_goto_nextway(GtkMenuItem *item);
+gboolean menu_cb_view_goto_nearpoi(GtkMenuItem *item);
+
+void menu_maps_remove_repos();
+void menu_maps_add_repos();
+void menu_init();
+
+#endif /* ifndef MAEMO_MAPPER_MENU_H */
diff --git a/src/path.c b/src/path.c
new file mode 100644 (file)
index 0000000..212f6a1
--- /dev/null
@@ -0,0 +1,1598 @@
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#define _GNU_SOURCE
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <osso-helplib.h>
+#include <bt-dbus.h>
+#include <hildon-widgets/hildon-note.h>
+#include <hildon-widgets/hildon-banner.h>
+#include <hildon-widgets/hildon-system-sound.h>
+#include <hildon-widgets/hildon-input-mode-hint.h>
+#include <sqlite3.h>
+
+#include "types.h"
+#include "data.h"
+#include "defines.h"
+
+#include "display.h"
+#include "gdk-pixbuf-rotate.h"
+#include "gpx.h"
+#include "main.h"
+#include "path.h"
+#include "poi.h"
+#include "util.h"
+
+typedef struct _OriginToggleInfo OriginToggleInfo;
+struct _OriginToggleInfo {
+    GtkWidget *rad_use_gps;
+    GtkWidget *rad_use_route;
+    GtkWidget *rad_use_text;
+    GtkWidget *chk_avoid_highways;
+    GtkWidget *chk_auto;
+    GtkWidget *txt_from;
+    GtkWidget *txt_to;
+};
+
+/* _near_point is the route point to which we are closest. */
+static Point *_near_point = NULL;
+static gint64 _near_point_dist_squared = INT64_MAX;
+
+/* _next_way is what we currently interpret to be the next waypoint. */
+static WayPoint *_next_way;
+static gint64 _next_way_dist_squared = INT64_MAX;
+
+/* _next_wpt is the route point immediately following _next_way. */
+static Point *_next_wpt = NULL;
+static gint64 _next_wpt_dist_squared = INT64_MAX;
+
+static gfloat _initial_distance_from_waypoint = -1.f;
+static WayPoint *_initial_distance_waypoint = NULL;
+
+static sqlite3 *_path_db = NULL;
+static sqlite3_stmt *_track_stmt_select = NULL;
+static sqlite3_stmt *_track_stmt_delete_path = NULL;
+static sqlite3_stmt *_track_stmt_delete_way = NULL;
+static sqlite3_stmt *_track_stmt_insert_path = NULL;
+static sqlite3_stmt *_track_stmt_insert_way = NULL;
+static sqlite3_stmt *_route_stmt_select = NULL;
+static sqlite3_stmt *_route_stmt_delete_path = NULL;
+static sqlite3_stmt *_route_stmt_delete_way = NULL;
+static sqlite3_stmt *_route_stmt_insert_path = NULL;
+static sqlite3_stmt *_route_stmt_insert_way = NULL;
+static sqlite3_stmt *_path_stmt_trans_begin = NULL;
+static sqlite3_stmt *_path_stmt_trans_commit = NULL;
+static sqlite3_stmt *_path_stmt_trans_rollback = NULL;
+
+static gchar *_last_spoken_phrase;
+
+void
+path_resize(Path *path, gint size)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(path->head + size != path->cap)
+    {
+        Point *old_head = path->head;
+        WayPoint *curr;
+        path->head = g_renew(Point, old_head, size);
+        path->cap = path->head + size;
+        if(path->head != old_head)
+        {
+            path->tail = path->head + (path->tail - old_head);
+
+            /* Adjust all of the waypoints. */
+            for(curr = path->whead - 1; curr++ != path->wtail; )
+                curr->point = path->head + (curr->point - old_head);
+        }
+    }
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+void
+path_wresize(Path *path, gint wsize)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(path->whead + wsize != path->wcap)
+    {
+        WayPoint *old_whead = path->whead;
+        path->whead = g_renew(WayPoint, old_whead, wsize);
+        path->wtail = path->whead + (path->wtail - old_whead);
+        path->wcap = path->whead + wsize;
+    }
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+static void
+read_path_from_db(Path *path, sqlite3_stmt *select_stmt)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    MACRO_PATH_INIT(*path);
+    while(SQLITE_ROW == sqlite3_step(select_stmt))
+    {
+        const gchar *desc;
+
+        MACRO_PATH_INCREMENT_TAIL(*path);
+        path->tail->unitx = sqlite3_column_int(select_stmt, 0);
+        path->tail->unity = sqlite3_column_int(select_stmt, 1);
+        path->tail->time = sqlite3_column_int(select_stmt, 2);
+        path->tail->altitude = sqlite3_column_int(select_stmt, 3);
+
+        desc = sqlite3_column_text(select_stmt, 4);
+        if(desc)
+        {
+            MACRO_PATH_INCREMENT_WTAIL(*path);
+            path->wtail->point = path->tail;
+            path->wtail->desc = g_strdup(desc);
+        }
+    }
+    sqlite3_reset(select_stmt);
+
+    /* If the last point isn't null, then add another null point. */
+    if(path->tail->unity)
+    {
+        MACRO_PATH_INCREMENT_TAIL(*path);
+        *path->tail = _point_null;
+    }
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+/* Returns the new next_update_index. */
+static gint
+write_path_to_db(Path *path,
+        sqlite3_stmt *delete_path_stmt,
+        sqlite3_stmt *delete_way_stmt,
+        sqlite3_stmt *insert_path_stmt,
+        sqlite3_stmt *insert_way_stmt,
+        gint index_last_saved)
+{
+    Point *curr;
+    WayPoint *wcurr;
+    gint num;
+    gboolean success = TRUE;
+    printf("%s(%d)\n", __PRETTY_FUNCTION__, index_last_saved);
+
+    /* Start transaction. */
+    sqlite3_step(_path_stmt_trans_begin);
+    sqlite3_reset(_path_stmt_trans_begin);
+
+    if(index_last_saved == 0)
+    {
+        /* Replace the whole thing, so delete the table first. */
+        if(SQLITE_DONE != sqlite3_step(delete_way_stmt)
+                || SQLITE_DONE != sqlite3_step(delete_path_stmt))
+        {
+            gchar buffer[BUFFER_SIZE];
+            snprintf(buffer, sizeof(buffer), "%s\n%s",
+                    _("Failed to write to path database. "
+                        "Tracks and routes may not be saved."),
+                    sqlite3_errmsg(_path_db));
+            popup_error(_window, buffer);
+            success = FALSE;
+        }
+        sqlite3_reset(delete_way_stmt);
+        sqlite3_reset(delete_path_stmt);
+    }
+
+    for(num = index_last_saved, curr = path->head + num, wcurr = path->whead;
+            success && ++curr <= path->tail; ++num)
+    {
+        /* If this is the last point, and it is null, don't write it. */
+        if(curr == path->tail && !curr->unity)
+            break;
+
+        /* Insert the path point. */
+        if(SQLITE_OK != sqlite3_bind_int(insert_path_stmt, 1, curr->unitx)
+        || SQLITE_OK != sqlite3_bind_int(insert_path_stmt, 2, curr->unity)
+        || SQLITE_OK != sqlite3_bind_int(insert_path_stmt, 3, curr->time)
+        || SQLITE_OK != sqlite3_bind_int(insert_path_stmt, 4, curr->altitude)
+        || SQLITE_DONE != sqlite3_step(insert_path_stmt))
+        {
+            gchar buffer[BUFFER_SIZE];
+            snprintf(buffer, sizeof(buffer), "%s\n%s",
+                    _("Failed to write to path database. "
+                        "Tracks and routes may not be saved."),
+                    sqlite3_errmsg(_path_db));
+            popup_error(_window, buffer);
+            success = FALSE;
+        }
+        sqlite3_reset(insert_path_stmt);
+
+        /* Now, check if curr is a waypoint. */
+        if(success && wcurr <= path->wtail && wcurr->point == curr)
+        {
+            gint num = sqlite3_last_insert_rowid(_path_db);
+            if(SQLITE_OK != sqlite3_bind_int(insert_way_stmt, 1, num)
+            || SQLITE_OK != sqlite3_bind_text(insert_way_stmt, 2, wcurr->desc,
+                -1, SQLITE_STATIC)
+            || SQLITE_DONE != sqlite3_step(insert_way_stmt))
+            {
+                gchar buffer[BUFFER_SIZE];
+                snprintf(buffer, sizeof(buffer), "%s\n%s",
+                        _("Failed to write to path database. "
+                            "Tracks and routes may not be saved."),
+                        sqlite3_errmsg(_path_db));
+                popup_error(_window, buffer);
+                success = FALSE;
+            }
+            sqlite3_reset(insert_way_stmt);
+            wcurr++;
+        }
+    }
+    if(success)
+    {
+        sqlite3_step(_path_stmt_trans_commit);
+        sqlite3_reset(_path_stmt_trans_commit);
+        vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+        return num;
+    }
+    else
+    {
+        sqlite3_step(_path_stmt_trans_rollback);
+        sqlite3_reset(_path_stmt_trans_rollback);
+        vprintf("%s(): return 0\n", __PRETTY_FUNCTION__);
+        return index_last_saved;
+    }
+}
+
+void
+path_save_route_to_db()
+{
+    if(_path_db)
+    {
+        write_path_to_db(&_route,
+                          _route_stmt_delete_path,
+                          _route_stmt_delete_way,
+                          _route_stmt_insert_path,
+                          _route_stmt_insert_way,
+                          0);
+    }
+}
+
+static void
+path_save_track_to_db()
+{
+    if(_path_db)
+    {
+        write_path_to_db(&_track,
+                          _track_stmt_delete_path,
+                          _track_stmt_delete_way,
+                          _track_stmt_insert_path,
+                          _track_stmt_insert_way,
+                          0);
+    }
+}
+
+static void
+path_update_track_in_db()
+{
+    if(_path_db)
+    {
+        _track_index_last_saved = write_path_to_db(&_track,
+                          _track_stmt_delete_path,
+                          _track_stmt_delete_way,
+                          _track_stmt_insert_path,
+                          _track_stmt_insert_way,
+                          _track_index_last_saved);
+    }
+}
+
+/**
+ * Updates _near_point, _next_way, and _next_wpt.  If quick is FALSE (as
+ * it is when this function is called from route_find_nearest_point), then
+ * the entire list (starting from _near_point) is searched.  Otherwise, we
+ * stop searching when we find a point that is farther away.
+ */
+static gboolean
+route_update_nears(gboolean quick)
+{
+    gboolean ret = FALSE;
+    Point *curr, *near;
+    WayPoint *wcurr, *wnext;
+    gint64 near_dist_squared;
+    printf("%s(%d)\n", __PRETTY_FUNCTION__, quick);
+
+    /* If we have waypoints (_next_way != NULL), then determine the "next
+     * waypoint", which is defined as the waypoint after the nearest point,
+     * UNLESS we've passed that waypoint, in which case the waypoint after
+     * that waypoint becomes the "next" waypoint. */
+    if(_next_way)
+    {
+        /* First, set near_dist_squared with the new distance from
+         * _near_point. */
+        near = _near_point;
+        near_dist_squared = DISTANCE_SQUARED(_pos, *near);
+
+        /* Now, search _route for a closer point.  If quick is TRUE, then we'll
+         * only search forward, only as long as we keep finding closer points.
+         */
+        for(curr = _near_point; curr++ != _route.tail; )
+        {
+            if(curr->unity)
+            {
+                gint dist_squared = DISTANCE_SQUARED(_pos, *curr);
+                if(dist_squared <= near_dist_squared)
+                {
+                    near = curr;
+                    near_dist_squared = dist_squared;
+                }
+                else if(quick)
+                    break;
+            }
+        }
+
+        /* Update _near_point. */
+        _near_point = near;
+        _near_point_dist_squared = near_dist_squared;
+
+        for(wnext = wcurr = _next_way; wcurr <= _route.wtail; wcurr++)
+        {
+            if(wcurr->point < near
+            /* Okay, this else if expression warrants explanation.  If the
+             * nearest track point happens to be a waypoint, then we want to
+             * check if we have "passed" that waypoint.  To check this, we
+             * test the distance from _pos to the waypoint and from _pos to
+             * _next_wpt, and if the former is increasing and the latter is
+             * decreasing, then we have passed the waypoint, and thus we
+             * should skip it.  Note that if there is no _next_wpt, then
+             * there is no next waypoint, so we do not skip it in that case. */
+                || (wcurr->point == near && quick
+                    && (_next_wpt
+                     && (DISTANCE_SQUARED(_pos, *near) > _next_way_dist_squared
+                      && DISTANCE_SQUARED(_pos, *_next_wpt)
+                                                   < _next_wpt_dist_squared))))
+                wnext = wcurr + 1;
+            else
+                break;
+        }
+
+        if(wnext == _route.wtail && (wnext->point < near
+                || (wnext->point == near && quick
+                    && (_next_wpt
+                     && (DISTANCE_SQUARED(_pos, *near) > _next_way_dist_squared
+                      &&DISTANCE_SQUARED(_pos, *_next_wpt)
+                                                 < _next_wpt_dist_squared)))))
+        {
+            _next_way = NULL;
+            _next_wpt = NULL;
+            _next_way_dist_squared = INT64_MAX;
+            _next_wpt_dist_squared = INT64_MAX;
+            ret = TRUE;
+        }
+        /* Only update _next_way (and consequently _next_wpt) if _next_way is
+         * different, and record that fact for return. */
+        else
+        {
+            if(!quick || _next_way != wnext)
+            {
+                _next_way = wnext;
+                _next_wpt = wnext->point;
+                if(_next_wpt == _route.tail)
+                    _next_wpt = NULL;
+                else
+                {
+                    while(!(++_next_wpt)->unity)
+                    {
+                        if(_next_wpt == _route.tail)
+                        {
+                            _next_wpt = NULL;
+                            break;
+                        }
+                    }
+                }
+                ret = TRUE;
+            }
+            _next_way_dist_squared = DISTANCE_SQUARED(_pos, *wnext->point);
+            if(_next_wpt)
+                _next_wpt_dist_squared = DISTANCE_SQUARED(_pos, *_next_wpt);
+        }
+    }
+
+    vprintf("%s(): return %d\n", __PRETTY_FUNCTION__, ret);
+    return ret;
+}
+
+/**
+ * Reset the _near_point data by searching the entire route for the nearest
+ * route point and waypoint.
+ */
+void
+route_find_nearest_point()
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    /* Initialize _near_point to first non-zero point. */
+    _near_point = _route.head;
+    while(!_near_point->unity && _near_point != _route.tail)
+        _near_point++;
+
+    /* Initialize _next_way. */
+    if(_route.wtail < _route.whead
+            || (_autoroute_data.enabled && _route.wtail == _route.whead))
+        _next_way = NULL;
+    else
+        /* We have at least one waypoint. */
+        _next_way = _autoroute_data.enabled ? _route.whead + 1 : _route.whead;
+    _next_way_dist_squared = INT64_MAX;
+
+    /* Initialize _next_wpt. */
+    _next_wpt = NULL;
+    _next_wpt_dist_squared = INT64_MAX;
+
+    route_update_nears(FALSE);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+/**
+ * Show the distance from the current GPS location to the given point,
+ * following the route.  If point is NULL, then the distance is shown to the
+ * next waypoint.
+ */
+gboolean
+route_show_distance_to(Point *point)
+{
+    gchar buffer[80];
+    gfloat lat1, lon1, lat2, lon2;
+    gdouble sum = 0.0;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    /* If point is NULL, use the next waypoint. */
+    if(point == NULL && _next_way)
+        point = _next_way->point;
+
+    /* If point is still NULL, return an error. */
+    if(point == NULL)
+    {
+        printf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+        return FALSE;
+    }
+
+    unit2latlon(_pos.unitx, _pos.unity, lat1, lon1);
+    if(point > _near_point)
+    {
+        Point *curr;
+        /* Skip _near_point in case we have already passed it. */
+        for(curr = _near_point + 1; curr <= point; ++curr)
+        {
+            if(curr->unity)
+            {
+                unit2latlon(curr->unitx, curr->unity, lat2, lon2);
+                sum += calculate_distance(lat1, lon1, lat2, lon2);
+                lat1 = lat2;
+                lon1 = lon2;
+            }
+        }
+    }
+    else if(point < _near_point)
+    {
+        Point *curr;
+        /* Skip _near_point in case we have already passed it. */
+        for(curr = _near_point - 1; curr >= point; --curr)
+        {
+            if(curr->unity)
+            {
+                unit2latlon(curr->unitx, curr->unity, lat2, lon2);
+                sum += calculate_distance(lat1, lon1, lat2, lon2);
+                lat1 = lat2;
+                lon1 = lon2;
+            }
+        }
+    }
+    else
+    {
+        /* Waypoint _is_ the nearest point. */
+        unit2latlon(_near_point->unitx, _near_point->unity, lat2, lon2);
+        sum += calculate_distance(lat1, lon1, lat2, lon2);
+    }
+
+    snprintf(buffer, sizeof(buffer), "%s: %.02f %s", _("Distance"),
+            sum * UNITS_CONVERT[_units], UNITS_ENUM_TEXT[_units]);
+    MACRO_BANNER_SHOW_INFO(_window, buffer);
+
+    return TRUE;
+    printf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+}
+
+void
+route_show_distance_to_next()
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(!route_show_distance_to(NULL))
+    {
+        MACRO_BANNER_SHOW_INFO(_window, _("There is no next waypoint."));
+    }
+    printf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+void
+route_show_distance_to_last()
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(_route.head != _route.tail)
+    {
+        /* Find last non-zero point. */
+        Point *p;
+        for(p = _route.tail; !p->unity; p--) { }
+        route_show_distance_to(p);
+    }
+    else
+    {
+        MACRO_BANNER_SHOW_INFO(_window, _("The current route is empty."));
+    }
+    printf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+static void
+track_show_distance_from(Point *point)
+{
+    gchar buffer[80];
+    gfloat lat1, lon1, lat2, lon2;
+    gdouble sum = 0.0;
+    Point *curr;
+    unit2latlon(_pos.unitx, _pos.unity, lat1, lon1);
+
+    /* Skip _track.tail because that should be _pos. */
+    for(curr = _track.tail; curr > point; --curr)
+    {
+        if(curr->unity)
+        {
+            unit2latlon(curr->unitx, curr->unity, lat2, lon2);
+            sum += calculate_distance(lat1, lon1, lat2, lon2);
+            lat1 = lat2;
+            lon1 = lon2;
+        }
+    }
+
+    snprintf(buffer, sizeof(buffer), "%s: %.02f %s", _("Distance"),
+            sum * UNITS_CONVERT[_units], UNITS_ENUM_TEXT[_units]);
+    MACRO_BANNER_SHOW_INFO(_window, buffer);
+}
+
+void
+track_show_distance_from_last()
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    /* Find last zero point. */
+    if(_track.head != _track.tail)
+    {
+        Point *point;
+        /* Find last zero point. */
+        for(point = _track.tail; point->unity; point--) { }
+        track_show_distance_from(point);
+    }
+    else
+    {
+        MACRO_BANNER_SHOW_INFO(_window, _("The current track is empty."));
+    }
+    printf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+void
+track_show_distance_from_first()
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    /* Find last zero point. */
+    if(_track.head != _track.tail)
+        track_show_distance_from(_track.head);
+    else
+    {
+        MACRO_BANNER_SHOW_INFO(_window, _("The current track is empty."));
+    }
+    printf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+static gboolean
+route_download_and_setup(GtkWidget *parent, const gchar *source_url,
+        const gchar *from, const gchar *to,
+        gboolean avoid_highways, gint replace_policy)
+{
+    gchar *from_escaped;
+    gchar *to_escaped;
+    gchar *buffer;
+    gchar *bytes;
+    gint size;
+    GnomeVFSResult vfs_result;
+    printf("%s(%s, %s)\n", __PRETTY_FUNCTION__, from, to);
+
+    from_escaped = gnome_vfs_escape_string(from);
+    to_escaped = gnome_vfs_escape_string(to);
+    buffer = g_strdup_printf(source_url, from_escaped, to_escaped);
+    g_free(from_escaped);
+    g_free(to_escaped);
+
+    if(avoid_highways)
+    {
+        gchar *old = buffer;
+        buffer = g_strconcat(old, "&avoid_highways=on", NULL);
+        g_free(old);
+    }
+
+    /* Attempt to download the route from the server. */
+    if(GNOME_VFS_OK != (vfs_result = gnome_vfs_read_entire_file(
+                buffer, &size, &bytes)))
+    {
+        g_free(bytes);
+        popup_error(parent, gnome_vfs_result_to_string(vfs_result));
+        vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+        return FALSE;
+    }
+
+    if(strncmp(bytes, "<?xml", strlen("<?xml")))
+    {
+        /* Not an XML document - must be bad locations. */
+        popup_error(parent,
+                _("Invalid source or destination."));
+        g_free(bytes);
+        vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+        return FALSE;
+    }
+    /* Else, if GPS is enabled, replace the route, otherwise append it. */
+    else if(gpx_path_parse(&_route, bytes, size, replace_policy))
+    {
+        path_save_route_to_db();
+
+        /* Find the nearest route point, if we're connected. */
+        route_find_nearest_point();
+
+        map_force_redraw();
+
+        MACRO_BANNER_SHOW_INFO(_window, _("Route Downloaded"));
+        g_free(bytes);
+
+        vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+        return TRUE;
+    }
+    popup_error(parent, _("Error parsing GPX file."));
+    g_free(bytes);
+
+    vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+    return FALSE;
+}
+
+/**
+ * This function is periodically run to download updated auto-route data
+ * from the route source.
+ */
+static gboolean
+auto_route_dl_idle()
+{
+    gchar latstr[32], lonstr[32], latlonstr[80];
+    printf("%s(%f, %f, %s)\n", __PRETTY_FUNCTION__,
+            _gps.lat, _gps.lon, _autoroute_data.dest);
+
+    g_ascii_dtostr(latstr, 32, _gps.lat);
+    g_ascii_dtostr(lonstr, 32, _gps.lon);
+    snprintf(latlonstr, sizeof(latlonstr), "%s, %s", latstr, lonstr);
+
+    route_download_and_setup(_window, _autoroute_data.source_url, latlonstr,
+            _autoroute_data.dest, _autoroute_data.avoid_highways,0);
+
+    _autoroute_data.in_progress = FALSE;
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+    return FALSE;
+}
+
+void
+path_reset_route()
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    route_find_nearest_point();
+    MACRO_MAP_RENDER_DATA();
+    MACRO_QUEUE_DRAW_AREA();
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+}
+
+/**
+ * Add a point to the _track list.  This function is slightly overloaded,
+ * since it is what houses the check for "have we moved
+ * significantly": it also initiates the re-calculation of the _near_point
+ * data, as well as calling osso_display_state_on() when we have the focus.
+ *
+ * If a non-zero time is given, then the current position (as taken from the
+ * _pos variable) is appended to _track with the given time.  If time is zero,
+ * then _point_null is appended to _track with time zero (this produces a
+ * "break" in the track).
+ */
+gboolean
+track_add(time_t time, gboolean newly_fixed)
+{
+    gboolean show_directions = TRUE;
+    gint announce_thres_unsquared;
+    gboolean ret = FALSE;
+    printf("%s(%d, %d, %d, %d)\n", __PRETTY_FUNCTION__,
+            (guint)time, newly_fixed, _pos.unitx, _pos.unity);
+
+    if(!time)
+    {
+        /* This is a null point. */
+        MACRO_PATH_INCREMENT_TAIL(_track);
+        *_track.tail = _point_null;
+    }
+    else
+    {
+        gboolean moving = FALSE;
+        gboolean approaching_waypoint = FALSE;
+
+        if(!_track.tail->unity || ((_pos.unitx - _track.tail->unitx)
+                    * (_pos.unitx - _track.tail->unitx))
+                + ((_pos.unity - _track.tail->unity)
+                    * (_pos.unity - _track.tail->unity))
+                > (_draw_width * _draw_width))
+        {
+            ret = TRUE;
+            /* Update the nearest-waypoint data. */
+            if(_route.head != _route.tail
+                    && (newly_fixed ? (route_find_nearest_point(), TRUE)
+                                    : route_update_nears(TRUE)))
+            {
+                /* Nearest waypoint has changed - re-render paths. */
+                map_render_paths();
+                MACRO_QUEUE_DRAW_AREA();
+            }
+            if(_show_paths & TRACKS_MASK)
+            {
+                /* Instead of calling map_render_paths(), we'll draw the new
+                 * line ourselves and call gtk_widget_queue_draw_area(). */
+                gint tx1, ty1, tx2, ty2;
+                map_render_segment(_gc[COLORABLE_TRACK],
+                        _gc[COLORABLE_TRACK_BREAK],
+                        _track.tail->unitx, _track.tail->unity,
+                        _pos.unitx, _pos.unity);
+                if(_track.tail->unity)
+                {
+                    unit2screen(_track.tail->unitx, _track.tail->unity,
+                            tx1, ty1);
+                    unit2screen(_pos.unitx, _pos.unity, tx2, ty2);
+                    gtk_widget_queue_draw_area(_map_widget,
+                            MIN(tx1, tx2) - _draw_width,
+                            MIN(ty1, ty2) - _draw_width,
+                            abs(tx1 - tx2) + (2 * _draw_width),
+                            abs(ty1 - ty2) + (2 * _draw_width));
+                }
+            }
+            MACRO_PATH_INCREMENT_TAIL(_track);
+
+            *_track.tail = _pos;
+
+            if(_near_point_dist_squared > (200 * 200))
+            {
+                if(_autoroute_data.enabled && !_autoroute_data.in_progress)
+                {
+                    MACRO_BANNER_SHOW_INFO(_window,
+                            _("Recalculating directions..."));
+                    _autoroute_data.in_progress = TRUE;
+                    show_directions = FALSE;
+                    g_idle_add((GSourceFunc)auto_route_dl_idle, NULL);
+                }
+                else
+                {
+                    /* Reset the route to try and find the nearest point. */
+                    path_reset_route();
+                }
+            }
+
+            /* Keep the display on. */
+            moving = TRUE;
+        }
+
+        announce_thres_unsquared = (20+_gps.speed) * _announce_notice_ratio*2;
+
+        if(_initial_distance_waypoint
+               && (_next_way != _initial_distance_waypoint
+               ||  _next_way_dist_squared > (_initial_distance_from_waypoint
+                                           * _initial_distance_from_waypoint)))
+        {
+            /* We've moved on to the next waypoint, or we're really far from
+             * the current waypoint. */
+            if(_waypoint_banner)
+            {
+                gtk_widget_destroy(_waypoint_banner);
+                _waypoint_banner = NULL;
+            }
+            _initial_distance_from_waypoint = -1.f;
+            _initial_distance_waypoint = NULL;
+        }
+
+        /* Check if we should announce upcoming waypoints. */
+        if(_initial_distance_waypoint || _next_way_dist_squared
+                    < (announce_thres_unsquared * announce_thres_unsquared))
+        {
+            if(show_directions)
+            {
+                if(!_initial_distance_waypoint)
+                {
+                    /* First time we're close enough to this waypoint. */
+                    if(_enable_voice
+                            /* And that we haven't already announced it. */
+                            && strcmp(_next_way->desc, _last_spoken_phrase))
+                    {
+                        g_free(_last_spoken_phrase);
+                        _last_spoken_phrase = g_strdup(_next_way->desc);
+                        if(!fork())
+                        {
+                            /* We are the fork child.  Synthesize the voice. */
+                            hildon_play_system_sound(
+                                "/usr/share/sounds/ui-information_note.wav");
+                            sleep(1);
+#               define _voice_synth_path "/usr/bin/flite"
+                            printf("%s %s\n", _voice_synth_path,
+                                    _last_spoken_phrase);
+                            execl(_voice_synth_path, _voice_synth_path,
+                                    "-t", _last_spoken_phrase, (char *)NULL);
+                            exit(0);
+                        }
+                    }
+                    _initial_distance_from_waypoint
+                        = sqrtf(_next_way_dist_squared);
+                    _initial_distance_waypoint = _next_way;
+                    if(_next_wpt && _next_wpt->unity != 0)
+                    {
+                        /* Create a banner for us the show progress. */
+                        _waypoint_banner = hildon_banner_show_progress(
+                                _window, NULL, _next_way->desc);
+                    }
+                    else
+                    {
+                        /* This is the last point in a segment, i.e.
+                         * "Arrive at ..." - just announce. */
+                        MACRO_BANNER_SHOW_INFO(_window, _next_way->desc);
+                    }
+                }
+                else if(_waypoint_banner);
+                {
+                    /* We're already close to this waypoint. */
+                    gdouble fraction = 1.f - (sqrtf(_next_way_dist_squared)
+                            / _initial_distance_from_waypoint);
+                    BOUND(fraction, 0.f, 1.f);
+                    hildon_banner_set_fraction(
+                            HILDON_BANNER(_waypoint_banner), fraction);
+                }
+            }
+            approaching_waypoint = TRUE;
+        }
+        else if(_next_way_dist_squared > 2 * (_initial_distance_from_waypoint
+                                            * _initial_distance_from_waypoint))
+        {
+            /* We're too far away now - destroy the banner. */
+        }
+
+        UNBLANK_SCREEN(moving, approaching_waypoint);
+    }
+
+    /* Maybe update the track database. */
+    {
+        static time_t last_track_db_update = 0;
+        if(!time || (time - last_track_db_update > 60
+                && _track.tail - _track.head + 1 > _track_index_last_saved))
+        {
+            path_update_track_in_db();
+            last_track_db_update = time;
+        }
+    }
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+    return ret;
+}
+
+void
+track_clear()
+{
+    GtkWidget *confirm;
+
+    confirm = hildon_note_new_confirmation(GTK_WINDOW(_window),
+                            _("Really clear the track?"));
+
+    if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm))) {
+        MACRO_PATH_FREE(_track);
+        MACRO_PATH_INIT(_track);
+        path_save_track_to_db();
+        map_force_redraw();
+    }
+
+    gtk_widget_destroy(confirm);
+}
+
+void
+track_insert_break(gboolean temporary)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(_track.tail->unity)
+    {
+        gint x1, y1;
+        unit2screen(_track.tail->unitx, _track.tail->unity, x1, y1);
+
+        MACRO_PATH_INCREMENT_TAIL(_track);
+        *_track.tail = _point_null;
+
+        /* To mark a "waypoint" in a track, we'll add a (0, 0) point and then
+         * another instance of the most recent track point. */
+        if(temporary)
+        {
+            MACRO_PATH_INCREMENT_TAIL(_track);
+            *_track.tail = _track.tail[-2];
+        }
+
+        /** Instead of calling map_render_paths(), we'll just add the waypoint
+         * ourselves. */
+        /* Make sure this circle will be visible. */
+        if((x1 < _screen_width_pixels) && (y1 < _screen_height_pixels))
+            gdk_draw_arc(_map_pixmap, _gc[COLORABLE_TRACK_BREAK],
+                    FALSE, /* FALSE: not filled. */
+                    x1 - _draw_width,
+                    y1 - _draw_width,
+                    2 * _draw_width,
+                    2 * _draw_width,
+                    0, /* start at 0 degrees. */
+                    360 * 64);
+    }
+    else if(!temporary)
+    {
+        MACRO_BANNER_SHOW_INFO(_window, _("Break already inserted."));
+    }
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+/**
+ * Cancel the current auto-route.
+ */
+void
+cancel_autoroute()
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(_autoroute_data.enabled)
+    {
+        _autoroute_data.enabled = FALSE;
+        g_free(_autoroute_data.source_url);
+        _autoroute_data.source_url = NULL;
+        g_free(_autoroute_data.dest);
+        _autoroute_data.dest = NULL;
+        _autoroute_data.in_progress = FALSE;
+    }
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+WayPoint *
+find_nearest_waypoint(gint unitx, gint unity)
+{
+    WayPoint *wcurr;
+    WayPoint *wnear;
+    gint64 nearest_squared;
+    Point pos = { unitx, unity, 0, INT_MIN };
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    wcurr = wnear = _route.whead;
+    if(wcurr && wcurr <= _route.wtail)
+    {
+        nearest_squared = DISTANCE_SQUARED(pos, *(wcurr->point));
+
+        wnear = _route.whead;
+        while(++wcurr <=  _route.wtail)
+        {
+            gint64 test_squared = DISTANCE_SQUARED(pos, *(wcurr->point));
+            if(test_squared < nearest_squared)
+            {
+                wnear = wcurr;
+                nearest_squared = test_squared;
+            }
+        }
+
+        /* Only use the waypoint if it is within a 6*_draw_width square drawn
+         * around the position. This is consistent with select_poi(). */
+        if(abs(unitx - wnear->point->unitx) < pixel2unit(3 * _draw_width)
+            && abs(unity - wnear->point->unity) < pixel2unit(3 * _draw_width))
+            return wnear;
+    }
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+    return NULL;
+}
+
+static gboolean
+origin_type_selected(GtkWidget *toggle,
+        OriginToggleInfo *oti)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle)))
+    {
+        gtk_widget_set_sensitive(oti->txt_from, toggle == oti->rad_use_text);
+        gtk_widget_set_sensitive(oti->chk_auto, toggle == oti->rad_use_gps);
+    }
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+/**
+ * Display a dialog box to the user asking them to download a route.  The
+ * "From" and "To" textfields may be initialized using the first two
+ * parameters.  The third parameter, if set to TRUE, will cause the "Use GPS
+ * Location" checkbox to be enabled, which automatically sets the "From" to the
+ * current GPS position (this overrides any value that may have been passed as
+ * the "To" initializer).
+ * None of the passed strings are freed - that is left to the caller, and it is
+ * safe to free either string as soon as this function returns.
+ */
+gboolean
+route_download(gchar *to)
+{
+    static GtkWidget *dialog = NULL;
+    static GtkWidget *table = NULL;
+    static GtkWidget *label = NULL;
+    static GtkWidget *txt_source_url = NULL;
+    static OriginToggleInfo oti;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    conic_recommend_connected();
+
+    if(dialog == NULL)
+    {
+        GtkEntryCompletion *from_comp;
+        GtkEntryCompletion *to_comp;
+        dialog = gtk_dialog_new_with_buttons(_("Download Route"),
+                GTK_WINDOW(_window), GTK_DIALOG_MODAL,
+                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+                NULL);
+
+        /* Enable the help button. */
+        ossohelp_dialog_help_enable(
+                GTK_DIALOG(dialog), HELP_ID_DOWNROUTE, _osso);
+
+        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+                table = gtk_table_new(2, 5, FALSE), TRUE, TRUE, 0);
+
+        /* Source URL. */
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Source URL")),
+                0, 1, 0, 1, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                txt_source_url = gtk_entry_new(),
+                1, 4, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+        gtk_entry_set_width_chars(GTK_ENTRY(txt_source_url), 25);
+
+        /* Use GPS Location. */
+        gtk_table_attach(GTK_TABLE(table),
+                oti.rad_use_gps = gtk_radio_button_new_with_label(NULL,
+                    _("Use GPS Location")),
+                0, 2, 1, 2, GTK_FILL, 0, 2, 4);
+
+        /* Use End of Route. */
+        gtk_table_attach(GTK_TABLE(table),
+               oti.rad_use_route = gtk_radio_button_new_with_label_from_widget(
+                   GTK_RADIO_BUTTON(oti.rad_use_gps), _("Use End of Route")),
+               0, 2, 2, 3, GTK_FILL, 0, 2, 4);
+
+        gtk_table_attach(GTK_TABLE(table),
+                gtk_vseparator_new(),
+                2, 3, 1, 3, GTK_FILL, GTK_FILL, 2,4);
+
+        /* Auto. */
+        gtk_table_attach(GTK_TABLE(table),
+                oti.chk_auto = gtk_check_button_new_with_label(
+                    _("Auto-Update")),
+                3, 4, 1, 2, GTK_FILL, 0, 2, 4);
+
+        /* Avoid Highways. */
+        gtk_table_attach(GTK_TABLE(table),
+                oti.chk_avoid_highways = gtk_check_button_new_with_label(
+                    _("Avoid Highways")),
+                3, 4, 2, 3, GTK_FILL, 0, 2, 4);
+
+
+        /* Origin. */
+        gtk_table_attach(GTK_TABLE(table),
+                oti.rad_use_text = gtk_radio_button_new_with_label_from_widget(
+                    GTK_RADIO_BUTTON(oti.rad_use_gps), _("Origin")),
+                0, 1, 3, 4, GTK_FILL, 0, 2, 4);
+        gtk_table_attach(GTK_TABLE(table),
+                oti.txt_from = gtk_entry_new(),
+                1, 4, 3, 4, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+        gtk_entry_set_width_chars(GTK_ENTRY(oti.txt_from), 25);
+        g_object_set(G_OBJECT(oti.txt_from), HILDON_AUTOCAP, FALSE, NULL);
+
+        /* Destination. */
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Destination")),
+                0, 1, 4, 5, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                oti.txt_to = gtk_entry_new(),
+                1, 4, 4, 5, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+        gtk_entry_set_width_chars(GTK_ENTRY(oti.txt_to), 25);
+        g_object_set(G_OBJECT(oti.txt_to), HILDON_AUTOCAP, FALSE, NULL);
+
+
+        /* Set up auto-completion. */
+        from_comp = gtk_entry_completion_new();
+        gtk_entry_completion_set_model(from_comp, GTK_TREE_MODEL(_loc_model));
+        gtk_entry_completion_set_text_column(from_comp, 0);
+        gtk_entry_set_completion(GTK_ENTRY(oti.txt_from), from_comp);
+
+        to_comp = gtk_entry_completion_new();
+        gtk_entry_completion_set_model(to_comp, GTK_TREE_MODEL(_loc_model));
+        gtk_entry_completion_set_text_column(to_comp, 0);
+        gtk_entry_set_completion(GTK_ENTRY(oti.txt_to), to_comp);
+
+
+        g_signal_connect(G_OBJECT(oti.rad_use_gps), "toggled",
+                          G_CALLBACK(origin_type_selected), &oti);
+        g_signal_connect(G_OBJECT(oti.rad_use_route), "toggled",
+                          G_CALLBACK(origin_type_selected), &oti);
+        g_signal_connect(G_OBJECT(oti.rad_use_text), "toggled",
+                          G_CALLBACK(origin_type_selected), &oti);
+
+        //gtk_widget_set_sensitive(oti.chk_auto, FALSE);
+    }
+
+    /* Initialize fields. */
+
+    gtk_entry_set_text(GTK_ENTRY(txt_source_url), _route_dl_url);
+    if(to)
+        gtk_entry_set_text(GTK_ENTRY(oti.txt_to), to);
+
+    /* Use "End of Route" by default if they have a route. */
+    if(_route.head != _route.tail)
+    {
+        /* There is no route, so make it the default. */
+        gtk_widget_set_sensitive(oti.rad_use_route, TRUE);
+        gtk_toggle_button_set_active(
+                GTK_TOGGLE_BUTTON(oti.rad_use_route), TRUE);
+        gtk_widget_grab_focus(oti.rad_use_route);
+    }
+    /* Else use "GPS Location" if they have GPS enabled. */
+    else
+    {
+        /* There is no route, so desensitize "Use End of Route." */
+        gtk_widget_set_sensitive(oti.rad_use_route, FALSE);
+        if(_enable_gps)
+        {
+            gtk_toggle_button_set_active(
+                    GTK_TOGGLE_BUTTON(oti.rad_use_gps), TRUE);
+            gtk_widget_grab_focus(oti.rad_use_gps);
+        }
+        /* Else use text. */
+        else
+        {
+            gtk_toggle_button_set_active(
+                    GTK_TOGGLE_BUTTON(oti.rad_use_text), TRUE);
+            gtk_widget_grab_focus(oti.txt_from);
+        }
+    }
+
+    gtk_widget_show_all(dialog);
+
+    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
+    {
+        gchar buffer[BUFFER_SIZE];
+        const gchar *source_url, *from, *to;
+        gboolean avoid_highways;
+
+        source_url = gtk_entry_get_text(GTK_ENTRY(txt_source_url));
+        if(!strlen(source_url))
+        {
+            popup_error(dialog, _("Please specify a source URL."));
+            continue;
+        }
+        else
+        {
+            g_free(_route_dl_url);
+            _route_dl_url = g_strdup(source_url);
+        }
+
+        if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(oti.rad_use_gps)))
+        {
+            gchar strlat[32];
+            gchar strlon[32];
+            g_ascii_formatd(strlat, 32, "%.06f", _gps.lat);
+            g_ascii_formatd(strlon, 32, "%.06f", _gps.lon);
+            snprintf(buffer, sizeof(buffer), "%s, %s", strlat, strlon);
+            from = buffer;
+        }
+        else if(gtk_toggle_button_get_active(
+                    GTK_TOGGLE_BUTTON(oti.rad_use_route)))
+        {
+            gchar strlat[32];
+            gchar strlon[32];
+            Point *p;
+            gfloat lat, lon;
+
+            /* Use last non-zero route point. */
+            for(p = _route.tail; !p->unity; p--) { }
+
+            unit2latlon(p->unitx, p->unity, lat, lon);
+            g_ascii_formatd(strlat, 32, "%.06f", lat);
+            g_ascii_formatd(strlon, 32, "%.06f", lon);
+            snprintf(buffer, sizeof(buffer), "%s, %s", strlat, strlon);
+            from = buffer;
+        }
+        else
+        {
+            from = gtk_entry_get_text(GTK_ENTRY(oti.txt_from));
+        }
+
+        if(!strlen(from))
+        {
+            popup_error(dialog, _("Please specify a start location."));
+            continue;
+        }
+
+        to = gtk_entry_get_text(GTK_ENTRY(oti.txt_to));
+        if(!strlen(to))
+        {
+            popup_error(dialog, _("Please specify an end location."));
+            continue;
+        }
+
+        avoid_highways = gtk_toggle_button_get_active(
+                GTK_TOGGLE_BUTTON(oti.chk_avoid_highways));
+        if(route_download_and_setup(dialog, source_url, from, to,
+                gtk_toggle_button_get_active(
+                    GTK_TOGGLE_BUTTON(oti.chk_avoid_highways)),
+                (gtk_toggle_button_get_active(
+                    GTK_TOGGLE_BUTTON(oti.rad_use_gps)) ? 0 : 1)))
+        {
+            GtkTreeIter iter;
+
+            /* Cancel any autoroute that might be occurring. */
+            cancel_autoroute();
+
+            if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(oti.chk_auto)))
+            {
+                _autoroute_data.source_url = g_strdup(source_url);
+                _autoroute_data.dest = g_strdup(to);
+                _autoroute_data.avoid_highways = avoid_highways;
+                _autoroute_data.enabled = TRUE;
+            }
+
+            /* Save Origin in Route Locations list if not from GPS. */
+            if(gtk_toggle_button_get_active(
+                        GTK_TOGGLE_BUTTON(oti.rad_use_text))
+                && !g_slist_find_custom(_loc_list, from,
+                            (GCompareFunc)strcmp))
+            {
+                _loc_list = g_slist_prepend(_loc_list, g_strdup(from));
+                gtk_list_store_insert_with_values(_loc_model, &iter,
+                        INT_MAX, 0, from, -1);
+            }
+
+            /* Save Destination in Route Locations list. */
+            if(!g_slist_find_custom(_loc_list, to,
+                        (GCompareFunc)strcmp))
+            {
+                _loc_list = g_slist_prepend(_loc_list, g_strdup(to));
+                gtk_list_store_insert_with_values(_loc_model, &iter,
+                        INT_MAX, 0, to, -1);
+            }
+
+            /* Success! Get out of the while loop. */
+            break;
+        }
+        /* else let them try again. */
+    }
+
+    gtk_widget_hide(dialog); /* Destroying causes a crash (!?!?!??!) */
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+void
+route_add_way_dialog(gint unitx, gint unity)
+{
+    gfloat lat, lon;
+    gchar tmp1[LL_FMT_LEN], tmp2[LL_FMT_LEN], *p_latlon;
+    static GtkWidget *dialog = NULL;
+    static GtkWidget *table = NULL;
+    static GtkWidget *label = NULL;
+    static GtkWidget *txt_scroll = NULL;
+    static GtkWidget *txt_desc = NULL;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(dialog == NULL)
+    {
+        dialog = gtk_dialog_new_with_buttons(_("Add Waypoint"),
+                GTK_WINDOW(_window), GTK_DIALOG_MODAL,
+                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+                NULL);
+
+        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+                table = gtk_table_new(2, 2, FALSE), TRUE, TRUE, 0);
+
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Lat, Lon:")),
+                0, 1, 0, 1, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+
+        unit2latlon(unitx, unity, lat, lon);
+        lat_format(lat, tmp1);
+        lon_format(lon, tmp2);
+        p_latlon = g_strdup_printf("%s, %s", tmp1, tmp2);
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(p_latlon),
+                1, 2, 0, 1, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+        g_free(p_latlon);
+
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Description")),
+                0, 1, 1, 2, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+
+        txt_scroll = gtk_scrolled_window_new(NULL, NULL);
+        gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(txt_scroll),
+                                       GTK_SHADOW_IN);
+        gtk_table_attach(GTK_TABLE(table),
+                txt_scroll,
+                1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+
+        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(txt_scroll),
+                GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+
+        txt_desc = gtk_text_view_new ();
+        gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt_desc), GTK_WRAP_WORD);
+
+        gtk_container_add(GTK_CONTAINER(txt_scroll), txt_desc);
+        gtk_widget_set_size_request(GTK_WIDGET(txt_scroll), 400, 60);
+    }
+
+    gtk_text_buffer_set_text(
+            gtk_text_view_get_buffer(GTK_TEXT_VIEW(txt_desc)), "", 0);
+
+    gtk_widget_show_all(dialog);
+
+    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
+    {
+        GtkTextBuffer *tbuf;
+        GtkTextIter ti1, ti2;
+        gchar *desc;
+
+        tbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txt_desc));
+        gtk_text_buffer_get_iter_at_offset(tbuf, &ti1, 0);
+        gtk_text_buffer_get_end_iter(tbuf, &ti2);
+        desc = gtk_text_buffer_get_text(tbuf, &ti1, &ti2, TRUE);
+
+        if(*desc)
+        {
+            /* There's a description.  Add a waypoint. */
+            MACRO_PATH_INCREMENT_TAIL(_route);
+            _route.tail->unitx = unitx;
+            _route.tail->unity = unity;
+            _route.tail->time = 0;
+            _route.tail->altitude = 0;
+
+            MACRO_PATH_INCREMENT_WTAIL(_route);
+            _route.wtail->point = _route.tail;
+            _route.wtail->desc
+                = gtk_text_buffer_get_text(tbuf, &ti1, &ti2, TRUE);
+        }
+        else
+        {
+            GtkWidget *confirm;
+
+            g_free(desc);
+
+            confirm = hildon_note_new_confirmation(GTK_WINDOW(dialog),
+                    _("Creating a \"waypoint\" with no description actually "
+                        "adds a break point.  Is that what you want?"));
+
+            if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm)))
+            {
+                /* There's no description.  Add a break by adding a (0, 0)
+                 * point (if necessary), and then the ordinary route point. */
+                if(_route.tail->unity)
+                {
+                    MACRO_PATH_INCREMENT_TAIL(_route);
+                    *_route.tail = _point_null;
+                }
+
+                MACRO_PATH_INCREMENT_TAIL(_route);
+                _route.tail->unitx = unitx;
+                _route.tail->unity = unity;
+                _route.tail->time = 0;
+                _route.tail->altitude = 0;
+
+
+                gtk_widget_destroy(confirm);
+            }
+            else
+            {
+                gtk_widget_destroy(confirm);
+                continue;
+            }
+        }
+
+        route_find_nearest_point();
+        map_render_paths();
+        MACRO_QUEUE_DRAW_AREA();
+        break;
+    }
+    gtk_widget_hide(dialog);
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+WayPoint*
+path_get_next_way()
+{
+    return _next_way;
+}
+
+void
+path_init()
+{
+    gchar *settings_dir;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    /* Initialize settings_dir. */
+    settings_dir = gnome_vfs_expand_initial_tilde(CONFIG_DIR_NAME);
+    g_mkdir_with_parents(settings_dir, 0700);
+
+    /* Open path database. */
+    {   
+        gchar *path_db_file;
+
+        path_db_file = gnome_vfs_uri_make_full_from_relative(
+                settings_dir, CONFIG_PATH_DB_FILE);
+
+        if(!path_db_file || SQLITE_OK != sqlite3_open(path_db_file, &_path_db)
+        /* Open worked. Now create tables, failing if they already exist. */
+        || (sqlite3_exec(_path_db,
+                    "create table route_path ("
+                    "num integer primary key, "
+                    "unitx integer, "
+                    "unity integer, "
+                    "time integer, "
+                    "altitude integer)"
+                    ";"
+                    "create table route_way ("
+                    "route_point primary key, "
+                    "description text)"
+                    ";"
+                    "create table track_path ("
+                    "num integer primary key, "
+                    "unitx integer, "
+                    "unity integer, "
+                    "time integer, "
+                    "altitude integer)"
+                    ";"
+                    "create table track_way ("
+                    "track_point primary key, "
+                    "description text)",
+                    NULL, NULL, NULL), FALSE) /* !! Comma operator !! */
+            /* Create prepared statements - failure here is bad! */
+            || SQLITE_OK != sqlite3_prepare(_path_db,
+                    "select unitx, unity, time, altitude, description "
+                    "from route_path left join route_way on "
+                    "route_path.num = route_way.route_point "
+                    "order by route_path.num",
+                    -1, &_route_stmt_select, NULL)
+            || SQLITE_OK != sqlite3_prepare(_path_db,
+                    "select unitx, unity, time, altitude, description "
+                    "from track_path left join track_way on "
+                    "track_path.num = track_way.track_point "
+                    "order by track_path.num",
+                    -1, &_track_stmt_select, NULL)
+            || SQLITE_OK != sqlite3_prepare(_path_db,
+                    "delete from route_path",
+                    -1, &_route_stmt_delete_path, NULL)
+            || SQLITE_OK != sqlite3_prepare(_path_db,
+                    "delete from route_way",
+                    -1, &_route_stmt_delete_way, NULL)
+            || SQLITE_OK != sqlite3_prepare(_path_db,
+                    "insert into route_path (num, unitx, unity, time, altitude) "
+                    "values (NULL, ?, ?, ?, ?)",
+                    -1, &_route_stmt_insert_path, NULL)
+            || SQLITE_OK != sqlite3_prepare(_path_db,
+                    "insert into route_way (route_point, description) "
+                    "values (?, ?)",
+                    -1, &_route_stmt_insert_way, NULL)
+            || SQLITE_OK != sqlite3_prepare(_path_db,
+                    "delete from track_path",
+                    -1, &_track_stmt_delete_path, NULL)
+            || SQLITE_OK != sqlite3_prepare(_path_db,
+                    "delete from track_way",
+                    -1, &_track_stmt_delete_way, NULL)
+            || SQLITE_OK != sqlite3_prepare(_path_db,
+                    "insert into track_path (num, unitx, unity, time, altitude) "
+                    "values (NULL, ?, ?, ?, ?)",
+                    -1, &_track_stmt_insert_path, NULL)
+            || SQLITE_OK != sqlite3_prepare(_path_db,
+                    "insert into track_way (track_point, description) "
+                    "values (?, ?)",
+                    -1, &_track_stmt_insert_way, NULL)
+            || SQLITE_OK != sqlite3_prepare(_path_db, "begin transaction",
+                    -1, &_path_stmt_trans_begin, NULL)
+            || SQLITE_OK != sqlite3_prepare(_path_db, "commit transaction",
+                    -1, &_path_stmt_trans_commit, NULL)
+            || SQLITE_OK != sqlite3_prepare(_path_db, "rollback transaction",
+                    -1, &_path_stmt_trans_rollback, NULL))
+        {   
+            gchar buffer[BUFFER_SIZE];
+            snprintf(buffer, sizeof(buffer), "%s\n%s",
+                    _("Failed to open path database. "
+                        "Tracks and routes will not be saved."),
+                    sqlite3_errmsg(_path_db));
+            sqlite3_close(_path_db);
+            _path_db = NULL;
+            popup_error(_window, buffer);
+        }
+        else
+        {   
+            read_path_from_db(&_route, _route_stmt_select);
+            read_path_from_db(&_track, _track_stmt_select);
+            _track_index_last_saved = _track.tail - _track.head - 1;
+        }
+        g_free(path_db_file);
+    }
+
+    g_free(settings_dir);
+
+    _last_spoken_phrase = g_strdup("");
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+void
+path_destroy()
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    /* Save paths. */
+    if(_track.tail->unity)
+        track_insert_break(FALSE);
+    path_update_track_in_db();
+    path_save_route_to_db();
+
+    if(_path_db)
+    {   
+        sqlite3_close(_path_db);
+        _path_db = NULL;
+    }
+
+    MACRO_PATH_FREE(_track);
+    MACRO_PATH_FREE(_route);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
diff --git a/src/path.h b/src/path.h
new file mode 100644 (file)
index 0000000..f63db63
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAEMO_MAPPER_PATH_H
+#define MAEMO_MAPPER_PATH_H
+
+void path_resize(Path *path, gint size);
+void path_wresize(Path *path, gint wsize);
+
+void path_save_route_to_db();
+
+void route_find_nearest_point();
+gboolean route_show_distance_to(Point *point);
+void route_show_distance_to_next();
+void route_show_distance_to_last();
+
+void track_show_distance_from_last();
+void track_show_distance_from_first();
+
+gboolean track_add(time_t time, gboolean newly_fixed);
+void track_clear();
+void track_insert_break(gboolean temporary);
+
+void path_reset_route();
+
+void cancel_autoroute();
+
+WayPoint * find_nearest_waypoint(gint unitx, gint unity);
+
+gboolean route_download(gchar *to);
+void route_add_way_dialog(gint unitx, gint unity);
+
+WayPoint* path_get_next_way();
+
+void path_init();
+void path_destroy();
+
+#endif /* ifndef MAEMO_MAPPER_PATH_H */
diff --git a/src/poi.c b/src/poi.c
new file mode 100644 (file)
index 0000000..bbecbcd
--- /dev/null
+++ b/src/poi.c
@@ -0,0 +1,2916 @@
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#define _GNU_SOURCE
+
+#include <string.h>
+#include <math.h>
+#include <osso-helplib.h>
+#include <hildon-widgets/hildon-note.h>
+#include <hildon-widgets/hildon-file-chooser-dialog.h>
+#include <hildon-widgets/hildon-number-editor.h>
+#include <hildon-widgets/hildon-banner.h>
+#include <hildon-widgets/hildon-input-mode-hint.h>
+
+#include <sqlite3.h>
+
+#include "types.h"
+#include "data.h"
+#include "defines.h"
+
+#include "display.h"
+#include "gdk-pixbuf-rotate.h"
+#include "gpx.h"
+#include "main.h"
+#include "poi.h"
+#include "util.h"
+
+static sqlite3 *_poi_db = NULL;
+static sqlite3_stmt *_stmt_browse_poi = NULL;
+static sqlite3_stmt *_stmt_browsecat_poi = NULL;
+static sqlite3_stmt *_stmt_select_poi = NULL;
+static sqlite3_stmt *_stmt_select_nearest_poi = NULL;
+static sqlite3_stmt *_stmt_insert_poi = NULL;
+static sqlite3_stmt *_stmt_update_poi = NULL;
+static sqlite3_stmt *_stmt_delete_poi = NULL;
+static sqlite3_stmt *_stmt_delete_poi_by_catid = NULL;
+static sqlite3_stmt *_stmt_nextlabel_poi = NULL;
+static sqlite3_stmt *_stmt_select_cat = NULL;
+static sqlite3_stmt *_stmt_insert_cat = NULL;
+static sqlite3_stmt *_stmt_update_cat = NULL;
+static sqlite3_stmt *_stmt_delete_cat = NULL;
+static sqlite3_stmt *_stmt_toggle_cat = NULL;
+static sqlite3_stmt *_stmt_selall_cat = NULL;
+
+typedef struct _PoiListInfo PoiListInfo;
+struct _PoiListInfo
+{
+    GtkWidget *dialog;
+    GtkWidget *dialog2;
+    GtkTreeViewColumn *select_column;
+    GtkWidget *tree_view;
+    gboolean select_all;
+};
+
+typedef struct _OriginToggleInfo OriginToggleInfo;
+struct _OriginToggleInfo {
+    GtkWidget *rad_use_gps;
+    GtkWidget *rad_use_route;
+    GtkWidget *rad_use_text;
+    GtkWidget *txt_origin;
+    GtkWidget *txt_query;
+};
+
+void
+poi_db_connect()
+{
+    gchar buffer[100];
+    gchar **pszResult;
+    gint nRow, nColumn;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(_poi_db)
+    {
+        sqlite3_close(_poi_db);
+        _poi_db = NULL;
+    }
+
+    if(!_poi_db_filename)
+    {
+        /* Do nothing. */
+    }
+    else if(SQLITE_OK != (sqlite3_open(_poi_db_filename, &_poi_db)))
+    {
+        gchar buffer2[BUFFER_SIZE];
+        snprintf(buffer2, sizeof(buffer2),
+                "%s: %s", _("Error with POI database"),
+                sqlite3_errmsg(_poi_db));
+        sqlite3_close(_poi_db);
+        _poi_db = NULL;
+        popup_error(_window, buffer2);
+    }
+    else if(SQLITE_OK != sqlite3_get_table(_poi_db,
+                "select label from poi limit 1",
+                &pszResult, &nRow, &nColumn, NULL))
+    {
+        gchar *create_sql = sqlite3_mprintf(
+                "create table poi (poi_id integer PRIMARY KEY, lat real, "
+                "lon real, label text, desc text, cat_id integer);"
+                "create table category (cat_id integer PRIMARY KEY,"
+                "label text, desc text, enabled integer);"
+                /* Add some default categories... */
+                "insert into category (label, desc, enabled) "
+                    "values ('%q', '%q', 1); "
+                "insert into category (label, desc, enabled) "
+                    "values ('%q', '%q', 1); "
+                "insert into category (label, desc, enabled) "
+                    "values ('%q', '%q', 1); "
+                "insert into category (label, desc, enabled) "
+                    "values ('%q', '%q', 1); "
+                "insert into category (label, desc, enabled) "
+                    "values ('%q', '%q', 1); "
+                "insert into category (label, desc, enabled) "
+                    "values ('%q', '%q', 1); "
+                "insert into category (label, desc, enabled) "
+                    "values ('%q', '%q', 1); "
+                "insert into category (label, desc, enabled) "
+                    "values ('%q', '%q', 1); "
+                "insert into category (label, desc, enabled) "
+                    "values ('%q', '%q', 1); "
+                "insert into category (label, desc, enabled) "
+                    "values ('%q', '%q', 1); "
+                "insert into category (label, desc, enabled) "
+                    "values ('%q', '%q', 1); ",
+                _("Service Station"),
+                _("Stations for purchasing fuel for vehicles."),
+                _("Residence"),
+                _("Houses, apartments, or other residences of import."),
+                _("Restaurant"),
+                _("Places to eat or drink."),
+                _("Shopping/Services"),
+                _("Places to shop or acquire services."),
+                _("Recreation"),
+                _("Indoor or Outdoor places to have fun."),
+                _("Transportation"),
+                _("Bus stops, airports, train stations, etc."),
+                _("Lodging"),
+                _("Places to stay temporarily or for the night."),
+                _("School"),
+                _("Elementary schools, college campuses, etc."),
+                _("Business"),
+                _("General places of business."),
+                _("Landmark"),
+                _("General landmarks."),
+                _("Other"),
+                _("Miscellaneous category for everything else."));
+
+        if(SQLITE_OK != sqlite3_exec(_poi_db, create_sql, NULL, NULL, NULL)
+                && (SQLITE_OK != sqlite3_get_table(_poi_db,
+                        "select label from poi limit 1",
+                        &pszResult, &nRow, &nColumn, NULL)))
+        {
+            snprintf(buffer, sizeof(buffer), "%s:\n%s",
+                    _("Failed to open or create database"),
+                    sqlite3_errmsg(_poi_db));
+            sqlite3_close(_poi_db);
+            _poi_db = NULL;
+            popup_error(_window, buffer);
+        }
+    }
+    else
+        sqlite3_free_table(pszResult);
+
+    if(_poi_db)
+    {
+        /* Prepare our SQL statements. */
+        /* browse poi */
+        sqlite3_prepare(_poi_db,
+                        "select p.poi_id, p.cat_id, p.lat, p.lon,"
+                        " p.label, p.desc, c.label"
+                        " from poi p inner join category c"
+                        "   on p.cat_id = c.cat_id"
+                        " where c.enabled = 1"
+                        " and p.label like $QUERY or p.desc like $QUERY"
+                        " order by (($LAT - p.lat) * ($LAT - p.lat) "
+                                 "+ ($LON - p.lon) * ($LON - p.lon)) DESC",
+                        -1, &_stmt_browse_poi, NULL);
+
+        /* browse poi by category */
+        sqlite3_prepare(_poi_db,
+                        "select p.poi_id, p.cat_id, p.lat, p.lon,"
+                        " p.label, p.desc, c.label"
+                        " from poi p inner join category c"
+                        "   on p.cat_id = c.cat_id"
+                        " where c.enabled = 1"
+                        " and p.cat_id = $CATID"
+                        " and ( p.label like $QUERY or p.desc like $QUERY )"
+                        " order by (($LAT - p.lat) * ($LAT - p.lat) "
+                                 "+ ($LON - p.lon) * ($LON - p.lon)) DESC",
+                        -1, &_stmt_browsecat_poi, NULL);
+
+        /* Prepare our SQL statements. */
+        /* select from poi */
+        sqlite3_prepare(_poi_db,
+                        "select p.lat, p.lon, p.poi_id, p.label, p.desc,"
+                        " p.cat_id, c.label, c.desc"
+                        " from poi p inner join category c"
+                        "    on p.cat_id = c.cat_id"
+                        " where c.enabled = 1"
+                        " and p.lat between ? and ? "
+                        " and p.lon between ? and ? ",
+                        -1, &_stmt_select_poi, NULL);
+
+        /* select nearest pois */
+        sqlite3_prepare(_poi_db,
+                        "select p.poi_id, p.cat_id, p.lat, p.lon,"
+                        " p.label, p.desc, c.label"
+                        " from poi p inner join category c"
+                        "   on p.cat_id = c.cat_id"
+                        " where c.enabled = 1"
+                        " order by (($LAT - p.lat) * ($LAT - p.lat) "
+                                 "+ ($LON - p.lon) * ($LON - p.lon)) limit 1",
+                        -1, &_stmt_select_nearest_poi, NULL);
+
+        /* insert poi */
+        sqlite3_prepare(_poi_db,
+                            "insert into poi (lat, lon, label, desc, cat_id)"
+                            " values (?, ?, ?, ?, ?)",
+                        -1, &_stmt_insert_poi, NULL);
+        /* update poi */
+        sqlite3_prepare(_poi_db,
+                            "update poi set lat = ?, lon = ?, "
+                            "label = ?, desc = ?, cat_id = ? where poi_id = ?",
+                        -1, &_stmt_update_poi, NULL);
+        /* delete from poi */
+        sqlite3_prepare(_poi_db,
+                        " delete from poi where poi_id = ?",
+                        -1, &_stmt_delete_poi, NULL);
+        /* delete from poi by cat_id */
+        sqlite3_prepare(_poi_db,
+                        "delete from poi where cat_id = ?",
+                        -1, &_stmt_delete_poi_by_catid, NULL);
+        /* get next poilabel */
+        sqlite3_prepare(_poi_db,
+                        "select ifnull(max(poi_id) + 1,1) from poi",
+                        -1, &_stmt_nextlabel_poi, NULL);
+
+        /* select from category */
+        sqlite3_prepare(_poi_db,
+                        "select c.label, c.desc, c.enabled"
+                        " from category c where c.cat_id = ?",
+                        -1, &_stmt_select_cat, NULL);
+        /* insert into category */
+        sqlite3_prepare(_poi_db,
+                        "insert into category (label, desc, enabled)"
+                        " values (?, ?, ?)",
+                        -1, &_stmt_insert_cat, NULL);
+        /* update category */
+        sqlite3_prepare(_poi_db,
+                        "update category set label = ?, desc = ?,"
+                        " enabled = ? where poi_id = ?",
+                        -1, &_stmt_update_cat, NULL);
+        /* delete from category */
+        sqlite3_prepare(_poi_db,
+                        "delete from category where cat_id = ?",
+                        -1, &_stmt_delete_cat, NULL);
+        /* enable category */
+        sqlite3_prepare(_poi_db,
+                        "update category set enabled = ?"
+                        " where cat_id = ?",
+                        -1, &_stmt_toggle_cat, NULL);
+        /* select all category */
+        sqlite3_prepare(_poi_db,
+                        "select c.cat_id, c.label, c.desc, c.enabled,"
+                        " count(p.poi_id)"
+                        " from category c"
+                        " left outer join poi p on c.cat_id = p.cat_id"
+                        " group by c.cat_id, c.label, c.desc, c.enabled "
+                        " order by c.label",
+                        -1, &_stmt_selall_cat, NULL);
+    }
+
+    _poi_enabled = _poi_db != NULL;
+
+    gtk_widget_set_sensitive(_menu_poi_item, _poi_enabled);
+    gtk_widget_set_sensitive(_cmenu_loc_add_poi_item, _poi_enabled);
+    gtk_widget_set_sensitive(_cmenu_loc_download_poi_item, _poi_enabled);
+    gtk_widget_set_sensitive(_cmenu_loc_browse_poi_item, _poi_enabled);
+    gtk_widget_set_sensitive(_cmenu_way_add_poi_item, _poi_enabled);
+    gtk_widget_set_sensitive(_cmenu_poi_submenu, _poi_enabled);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+gboolean
+get_nearest_poi(gint unitx, gint unity, PoiInfo *poi)
+{
+    printf("%s(%d, %d)\n", __PRETTY_FUNCTION__, unitx, unity);
+    gboolean result;
+    gfloat lat, lon;
+    unit2latlon(unitx, unity, lat, lon);
+
+    if(SQLITE_OK == sqlite3_bind_double(_stmt_select_nearest_poi, 1, lat)
+    && SQLITE_OK == sqlite3_bind_double(_stmt_select_nearest_poi, 2, lon)
+        && SQLITE_ROW == sqlite3_step(_stmt_select_nearest_poi))
+    {
+        poi->poi_id = sqlite3_column_int(_stmt_select_nearest_poi, 0);
+        poi->cat_id = sqlite3_column_int(_stmt_select_nearest_poi, 1);
+        poi->lat = sqlite3_column_double(_stmt_select_nearest_poi, 2);
+        poi->lon = sqlite3_column_double(_stmt_select_nearest_poi, 3);
+        poi->label =g_strdup(sqlite3_column_text(_stmt_select_nearest_poi, 4));
+        poi->desc = g_strdup(sqlite3_column_text(_stmt_select_nearest_poi, 5));
+        poi->clabel=g_strdup(sqlite3_column_text(_stmt_select_nearest_poi, 6));
+        result = TRUE;
+    }
+    else
+        result = FALSE;
+    sqlite3_reset(_stmt_select_nearest_poi);
+    vprintf("%s(): return %d\n", __PRETTY_FUNCTION__, result);
+    return result;
+}
+
+gboolean
+select_poi(gint unitx, gint unity, PoiInfo *poi, gboolean quick)
+{
+    gint x, y;
+    gfloat lat1, lon1, lat2, lon2;
+    static GtkWidget *dialog = NULL;
+    static GtkWidget *list = NULL;
+    static GtkWidget *sw = NULL;
+    static GtkTreeViewColumn *column = NULL;
+    static GtkCellRenderer *renderer = NULL;
+    GtkListStore *store = NULL;
+    GtkTreeIter iter;
+    gboolean selected = FALSE;
+    gchar tmp1[LL_FMT_LEN], tmp2[LL_FMT_LEN];
+    gint num_cats = 0;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    x = unitx - pixel2unit(3 * _draw_width);
+    y = unity + pixel2unit(3 * _draw_width);
+    unit2latlon(x, y, lat1, lon1);
+
+    x = unitx + pixel2unit(3 * _draw_width);
+    y = unity - pixel2unit(3 * _draw_width);
+    unit2latlon(x, y, lat2, lon2);
+
+    if(SQLITE_OK != sqlite3_bind_double(_stmt_select_poi, 1, lat1) ||
+          SQLITE_OK != sqlite3_bind_double(_stmt_select_poi, 2, lat2) ||
+          SQLITE_OK != sqlite3_bind_double(_stmt_select_poi, 3, lon1) ||
+          SQLITE_OK != sqlite3_bind_double(_stmt_select_poi, 4, lon2))
+    {
+        g_printerr("Failed to bind values for _stmt_select_poi\n");
+        return FALSE;
+    }
+
+    /* Initialize store. */
+    store = gtk_list_store_new(POI_NUM_COLUMNS,
+                               G_TYPE_BOOLEAN,/* Selected */
+                               G_TYPE_INT,    /* POI ID */
+                               G_TYPE_INT,    /* Category ID */
+                               G_TYPE_FLOAT,  /* Latitude */
+                               G_TYPE_FLOAT,  /* Longitude */
+                               G_TYPE_STRING, /* Lat/Lon */
+                               G_TYPE_FLOAT,  /* Bearing */
+                               G_TYPE_FLOAT,  /* Distance */
+                               G_TYPE_STRING, /* POI Label */
+                               G_TYPE_STRING, /* POI Desc. */
+                               G_TYPE_STRING);/* Category Label */
+
+    while(SQLITE_ROW == sqlite3_step(_stmt_select_poi))
+    {
+        gfloat lat, lon;
+        lat = sqlite3_column_double(_stmt_select_poi, 0);
+        lon = sqlite3_column_double(_stmt_select_poi, 1);
+        lat_format(lat, tmp1);
+        lon_format(lon, tmp2);
+        gtk_list_store_append(store, &iter);
+        gtk_list_store_set(store, &iter,
+                POI_POIID, sqlite3_column_int(_stmt_select_poi, 2),
+                POI_CATID, sqlite3_column_int(_stmt_select_poi, 5),
+                POI_LAT, lat,
+                POI_LON, lon,
+                POI_LATLON, g_strdup_printf("%s, %s", tmp1, tmp2),
+                POI_LABEL, sqlite3_column_text(_stmt_select_poi, 3),
+                POI_DESC, sqlite3_column_text(_stmt_select_poi, 4),
+                POI_CLABEL, sqlite3_column_text(_stmt_select_poi, 6),
+                -1);
+        num_cats++;
+    }
+    sqlite3_reset(_stmt_select_poi);
+
+    switch(num_cats)
+    {
+        case 0:
+            g_object_unref(G_OBJECT(store));
+            if(!quick)
+            {
+                MACRO_BANNER_SHOW_INFO(_window, _("No POIs found."));
+            }
+            return FALSE;
+            break;
+        case 1:
+            /* iter is still set to the most-recently added POI. */
+            gtk_tree_model_get(GTK_TREE_MODEL(store),
+                &iter,
+                POI_POIID, &(poi->poi_id),
+                POI_CATID, &(poi->cat_id),
+                POI_LAT, &(poi->lat),
+                POI_LON, &(poi->lon),
+                POI_LABEL, &(poi->label),
+                POI_DESC, &(poi->desc),
+                POI_CLABEL, &(poi->clabel),
+                -1);
+            g_object_unref(G_OBJECT(store));
+            return TRUE;
+            break;
+        default:
+            if(quick)
+            {
+                g_object_unref(G_OBJECT(store));
+                return get_nearest_poi(unitx, unity, poi);
+            }
+    }
+
+    /* There are at least 2 matching POI's - let the user select one. */
+    if(dialog == NULL)
+    {
+        dialog = gtk_dialog_new_with_buttons(_("Select POI"),
+                GTK_WINDOW(_window), GTK_DIALOG_MODAL,
+                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+                NULL);
+
+        gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 300);
+
+        sw = gtk_scrolled_window_new (NULL, NULL);
+        gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
+                GTK_SHADOW_ETCHED_IN);
+        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
+                GTK_POLICY_NEVER,
+                GTK_POLICY_AUTOMATIC);
+        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+                sw, TRUE, TRUE, 0);
+
+        list = gtk_tree_view_new();
+        gtk_container_add(GTK_CONTAINER(sw), list);
+
+        gtk_tree_selection_set_mode(
+                gtk_tree_view_get_selection(GTK_TREE_VIEW(list)),
+                GTK_SELECTION_SINGLE);
+        gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(list), TRUE);
+
+        renderer = gtk_cell_renderer_text_new();
+        column = gtk_tree_view_column_new_with_attributes(
+                _("Location"), renderer, "text", POI_LATLON, NULL);
+        gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);
+
+        renderer = gtk_cell_renderer_text_new();
+        column = gtk_tree_view_column_new_with_attributes(
+                _("Label"), renderer, "text", POI_LABEL, NULL);
+        gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);
+
+        renderer = gtk_cell_renderer_text_new();
+        column = gtk_tree_view_column_new_with_attributes(
+                _("Category"), renderer, "text", POI_CLABEL, NULL);
+        gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);
+    }
+
+    gtk_tree_view_set_model(GTK_TREE_VIEW(list), GTK_TREE_MODEL(store));
+    g_object_unref(G_OBJECT(store));
+
+    gtk_widget_show_all(dialog);
+
+    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
+    {
+        if(gtk_tree_selection_get_selected(
+                    gtk_tree_view_get_selection(GTK_TREE_VIEW(list)),
+                    NULL, &iter))
+        {
+            gtk_tree_model_get(GTK_TREE_MODEL(store), &iter,
+                POI_POIID, &(poi->poi_id),
+                POI_CATID, &(poi->cat_id),
+                POI_LAT, &(poi->lat),
+                POI_LON, &(poi->lon),
+                POI_LABEL, &(poi->label),
+                POI_DESC, &(poi->desc),
+                POI_CLABEL, &(poi->clabel),
+                -1);
+            selected = TRUE;
+            break;
+        }
+        else
+            popup_error(dialog, _("Select one POI from the list."));
+    }
+
+    map_force_redraw();
+
+    gtk_widget_hide(dialog);
+
+    vprintf("%s(): return %d\n", __PRETTY_FUNCTION__, selected);
+    return selected;
+}
+
+static gboolean
+category_delete(GtkWidget *widget, DeletePOI *dpoi)
+{
+    GtkWidget *confirm;
+    gint i;
+    gchar *buffer;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    buffer = g_strdup_printf("%s\n\t%s\n%s",
+            _("Delete category?"),
+            dpoi->txt_label,
+            _("WARNING: All POIs in that category will also be deleted!"));
+    confirm = hildon_note_new_confirmation (GTK_WINDOW(_window), buffer);
+    g_free(buffer);
+    i = gtk_dialog_run (GTK_DIALOG (confirm));
+    gtk_widget_destroy (GTK_WIDGET (confirm));
+
+    if(i == GTK_RESPONSE_OK)
+    {
+        /* delete dpoi->poi_id */
+        if(SQLITE_OK != sqlite3_bind_int(_stmt_delete_poi_by_catid, 1,
+                    dpoi->id) ||
+           SQLITE_DONE != sqlite3_step(_stmt_delete_poi_by_catid))
+        {
+            MACRO_BANNER_SHOW_INFO(_window, _("Error deleting POI"));
+            sqlite3_reset(_stmt_delete_poi_by_catid);
+            return FALSE;
+        }
+        sqlite3_reset(_stmt_delete_poi_by_catid);
+
+        if(SQLITE_OK != sqlite3_bind_int(_stmt_delete_cat, 1, dpoi->id) ||
+           SQLITE_DONE != sqlite3_step(_stmt_delete_cat))
+        {
+            MACRO_BANNER_SHOW_INFO(_window, _("Error deleting category"));
+            sqlite3_reset(_stmt_delete_cat);
+            return FALSE;
+        }
+        sqlite3_reset(_stmt_delete_cat);
+
+        map_force_redraw();
+        gtk_widget_hide_all(dpoi->dialog);
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+gboolean
+category_edit_dialog(gint cat_id)
+{
+    gchar *cat_label = NULL, *cat_desc = NULL;
+    gint cat_enabled;
+    GtkWidget *dialog;
+    GtkWidget *table;
+    GtkWidget *label;
+    GtkWidget *txt_label;
+    GtkWidget *txt_desc;
+    GtkWidget *btn_delete = NULL;
+    GtkWidget *txt_scroll;
+    GtkWidget *chk_enabled;
+    GtkTextBuffer *desc_txt;
+    GtkTextIter begin, end;
+    gboolean results = TRUE;
+    DeletePOI dpoi = {NULL, NULL, 0};
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(cat_id > 0)
+    {
+        if(SQLITE_OK != sqlite3_bind_double(_stmt_select_cat, 1, cat_id) ||
+           SQLITE_ROW != sqlite3_step(_stmt_select_cat))
+        {
+            vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+            sqlite3_reset(_stmt_select_cat);
+            return FALSE;
+        }
+
+        cat_label = g_strdup(sqlite3_column_text(_stmt_select_cat, 0));
+        cat_desc = g_strdup(sqlite3_column_text(_stmt_select_cat, 1));
+        cat_enabled = sqlite3_column_int(_stmt_select_cat, 2);
+
+        sqlite3_reset(_stmt_select_cat);
+
+        dialog = gtk_dialog_new_with_buttons(_("Edit Category"),
+            GTK_WINDOW(_window), GTK_DIALOG_MODAL,
+            GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+            NULL);
+
+        gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
+                btn_delete = gtk_button_new_with_label(_("Delete...")));
+
+        dpoi.dialog = dialog;
+        dpoi.txt_label = g_strdup(cat_label);
+        dpoi.id = cat_id;
+
+        g_signal_connect(G_OBJECT(btn_delete), "clicked",
+                          G_CALLBACK(category_delete), &dpoi);
+
+        gtk_dialog_add_button(GTK_DIALOG(dialog),
+                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
+    }
+    else
+    {
+        cat_enabled = 1;
+        cat_label = g_strdup("");
+        cat_id = 0;
+        cat_desc = g_strdup("");
+
+        dialog = gtk_dialog_new_with_buttons(_("Add Category"),
+            GTK_WINDOW(_window), GTK_DIALOG_MODAL,
+            GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+            GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+            NULL);
+    }
+
+    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+            table = gtk_table_new(6, 4, FALSE), TRUE, TRUE, 0);
+
+    gtk_table_attach(GTK_TABLE(table),
+            label = gtk_label_new(_("Label")),
+            0, 1, 0, 1, GTK_FILL, 0, 2, 4);
+    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+    gtk_table_attach(GTK_TABLE(table),
+            txt_label = gtk_entry_new(),
+            1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+
+    gtk_table_attach(GTK_TABLE(table),
+            label = gtk_label_new(_("Description")),
+            0, 1, 1, 2, GTK_FILL, 0, 2, 4);
+    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+
+    txt_scroll = gtk_scrolled_window_new(NULL, NULL);
+    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(txt_scroll),
+                                   GTK_SHADOW_IN);
+    gtk_table_attach(GTK_TABLE(table),
+            txt_scroll,
+            1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+
+    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(txt_scroll),
+                                 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+
+    txt_desc = gtk_text_view_new ();
+    gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt_desc), GTK_WRAP_WORD);
+
+    gtk_container_add(GTK_CONTAINER(txt_scroll), txt_desc);
+    gtk_widget_set_size_request(GTK_WIDGET(txt_scroll), 400, 60);
+
+    desc_txt = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txt_desc));
+
+    gtk_table_attach(GTK_TABLE(table),
+            chk_enabled = gtk_check_button_new_with_label(
+                _("Enabled")),
+            0, 2, 2, 3, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+
+    /* label */
+    gtk_entry_set_text(GTK_ENTRY(txt_label), cat_label);
+
+    /* desc */
+    gtk_text_buffer_set_text(desc_txt, cat_desc, -1);
+
+    /* enabled */
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chk_enabled),
+            (cat_enabled == 1 ? TRUE : FALSE));
+
+    g_free(cat_label);
+    cat_label = NULL;
+    g_free(cat_desc);
+    cat_desc = NULL;
+
+    gtk_widget_show_all(dialog);
+
+    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
+    {
+        if(strlen(gtk_entry_get_text(GTK_ENTRY(txt_label))))
+            cat_label = g_strdup(gtk_entry_get_text(GTK_ENTRY(txt_label)));
+        else
+        {
+            popup_error(dialog, _("Please specify a name for the category."));
+            continue;
+        }
+
+        gtk_text_buffer_get_iter_at_offset(desc_txt, &begin,0 );
+        gtk_text_buffer_get_end_iter (desc_txt, &end);
+        cat_desc = gtk_text_buffer_get_text(desc_txt, &begin, &end, TRUE);
+
+        cat_enabled = (gtk_toggle_button_get_active(
+                GTK_TOGGLE_BUTTON(chk_enabled)) ? 1 : 0);
+
+        if(cat_id > 0)
+        {
+            /* edit category */
+            if(SQLITE_OK != sqlite3_bind_text(_stmt_update_cat, 1, cat_label,
+                        -1, g_free) ||
+               SQLITE_OK != sqlite3_bind_text(_stmt_update_cat, 2, cat_desc,
+                        -1, g_free) ||
+               SQLITE_OK != sqlite3_bind_int(_stmt_update_cat, 3,cat_enabled)||
+               SQLITE_OK != sqlite3_bind_int(_stmt_update_cat, 4, cat_id) ||
+               SQLITE_DONE != sqlite3_step(_stmt_update_cat))
+            {
+                MACRO_BANNER_SHOW_INFO(_window,_("Error updating category"));
+                results = FALSE;
+            }
+            sqlite3_reset(_stmt_update_cat);
+        }
+        else
+        {
+            /* add category */
+            if(SQLITE_OK != sqlite3_bind_text(_stmt_insert_cat, 1, cat_label,
+                        -1, g_free) ||
+               SQLITE_OK != sqlite3_bind_text(_stmt_insert_cat, 2, cat_desc,
+                        -1, g_free) ||
+               SQLITE_OK != sqlite3_bind_int(_stmt_insert_cat, 3,cat_enabled)||
+               SQLITE_DONE != sqlite3_step(_stmt_insert_cat))
+            {
+                MACRO_BANNER_SHOW_INFO(_window, _("Error adding category"));
+                results = FALSE;
+            }
+            sqlite3_reset(_stmt_insert_cat);
+        }
+        break;
+    }
+
+    g_free(dpoi.txt_label);
+
+    g_object_unref (desc_txt);
+
+    if(results)
+        map_force_redraw();
+
+    gtk_widget_hide_all(dialog);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+    return results;
+}
+
+static void
+category_toggled(GtkCellRendererToggle *cell, gchar *path, GtkListStore **data)
+{
+    GtkTreeIter iter;
+    gboolean cat_enabled;
+    gint cat_id;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    GtkTreeModel *model = GTK_TREE_MODEL(*data);
+    if( !gtk_tree_model_get_iter_from_string(model, &iter, path) )
+        return;
+
+    gtk_tree_model_get(model, &iter,
+            CAT_ENABLED, &cat_enabled,
+            CAT_ID, &cat_id,
+            -1);
+
+    cat_enabled ^= 1;
+
+    if(SQLITE_OK != sqlite3_bind_int(_stmt_toggle_cat, 1, cat_enabled) ||
+       SQLITE_OK != sqlite3_bind_int(_stmt_toggle_cat, 2, cat_id) ||
+       SQLITE_DONE != sqlite3_step(_stmt_toggle_cat))
+    {
+        MACRO_BANNER_SHOW_INFO(_window, _("Error updating Category"));
+    }
+    else
+    {
+        gtk_list_store_set(GTK_LIST_STORE(model), &iter,
+                   CAT_ENABLED, cat_enabled, -1);
+        map_force_redraw();
+    }
+
+    sqlite3_reset(_stmt_toggle_cat);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+}
+
+static GtkListStore*
+generate_store()
+{
+    GtkTreeIter iter;
+    GtkListStore *store;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    store = gtk_list_store_new(CAT_NUM_COLUMNS,
+                               G_TYPE_UINT,
+                               G_TYPE_BOOLEAN,
+                               G_TYPE_STRING,
+                               G_TYPE_STRING,
+                               G_TYPE_UINT);
+
+    while(SQLITE_ROW == sqlite3_step(_stmt_selall_cat))
+    {
+        gtk_list_store_append(store, &iter);
+        gtk_list_store_set(store, &iter,
+                CAT_ID, sqlite3_column_int(_stmt_selall_cat, 0),
+                CAT_ENABLED, sqlite3_column_int(_stmt_selall_cat, 3),
+                CAT_LABEL, sqlite3_column_text(_stmt_selall_cat, 1),
+                CAT_DESC, sqlite3_column_text(_stmt_selall_cat, 2),
+                CAT_POI_CNT, sqlite3_column_int(_stmt_selall_cat, 4),
+                -1);
+    }
+    sqlite3_reset(_stmt_selall_cat);
+
+    vprintf("%s(): return %p\n", __PRETTY_FUNCTION__, store);
+    return store;
+}
+
+static gboolean
+category_add(GtkWidget *widget, GtkWidget *tree_view)
+{
+    GtkListStore *store;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(category_edit_dialog(0))
+    {
+        store = generate_store();
+        gtk_tree_view_set_model(
+                GTK_TREE_VIEW(tree_view),
+                GTK_TREE_MODEL(store));
+        g_object_unref(G_OBJECT(store));
+    }
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+category_edit(GtkWidget *widget, GtkWidget *tree_view)
+{
+    GtkTreeIter iter;
+    GtkTreeModel *store;
+    GtkTreeSelection *selection;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    store = gtk_tree_view_get_model(GTK_TREE_VIEW(tree_view));
+    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view));
+    if(gtk_tree_selection_get_selected(selection, &store, &iter))
+    {
+        GValue val;
+        memset(&val, 0, sizeof(val));
+        gtk_tree_model_get_value(store, &iter, 0, &val);
+        if(category_edit_dialog(g_value_get_uint(&val)))
+        {
+            GtkListStore *new_store = generate_store();
+            gtk_tree_view_set_model(
+                    GTK_TREE_VIEW(tree_view),
+                    GTK_TREE_MODEL(new_store));
+            g_object_unref(G_OBJECT(new_store));
+        }
+    }
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+gboolean
+category_list_dialog()
+{
+    static GtkWidget *dialog = NULL;
+    static GtkWidget *tree_view = NULL;
+    static GtkWidget *sw = NULL;
+    static GtkWidget *btn_edit = NULL;
+    static GtkWidget *btn_add = NULL;
+    static GtkTreeViewColumn *column = NULL;
+    static GtkCellRenderer *renderer = NULL;
+    static GtkListStore *store;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    store = generate_store();
+
+    if(!store)
+        return TRUE;
+
+    if(dialog == NULL)
+    {
+        dialog = gtk_dialog_new_with_buttons(_("POI Categories"),
+                GTK_WINDOW(_window), GTK_DIALOG_MODAL,
+                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+                NULL);
+
+        /* Enable the help button. */
+        ossohelp_dialog_help_enable(
+                GTK_DIALOG(dialog), HELP_ID_POICAT, _osso);
+
+        gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
+                btn_edit = gtk_button_new_with_label(_("Edit...")));
+
+        gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
+                btn_add = gtk_button_new_with_label(_("Add...")));
+
+        sw = gtk_scrolled_window_new(NULL, NULL);
+        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (sw),
+                      GTK_POLICY_NEVER,
+                      GTK_POLICY_AUTOMATIC);
+        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+                sw, TRUE, TRUE, 0);
+
+        tree_view = gtk_tree_view_new();
+        /* Maemo-related? */
+        g_object_set(tree_view, "allow-checkbox-mode", FALSE, NULL);
+        gtk_container_add (GTK_CONTAINER (sw), tree_view);
+
+        gtk_tree_selection_set_mode(
+                gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view)),
+                GTK_SELECTION_SINGLE);
+        gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree_view), TRUE);
+
+        renderer = gtk_cell_renderer_text_new();
+        column = gtk_tree_view_column_new_with_attributes(
+                _("ID"), renderer, "text", CAT_ID, NULL);
+        gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
+        gtk_tree_view_column_set_max_width (column, 1);
+
+        renderer = gtk_cell_renderer_toggle_new();
+        g_signal_connect (renderer, "toggled",
+                G_CALLBACK (category_toggled), &store);
+        column = gtk_tree_view_column_new_with_attributes(
+                _("Enabled"), renderer, "active", CAT_ENABLED, NULL);
+        gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
+
+        renderer = gtk_cell_renderer_text_new();
+        column = gtk_tree_view_column_new_with_attributes(
+                _("Label"), renderer, "text", CAT_LABEL, NULL);
+        gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
+
+        renderer = gtk_cell_renderer_text_new();
+        column = gtk_tree_view_column_new_with_attributes(
+                _("Description"), renderer, "text", CAT_DESC, NULL);
+        gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
+
+        renderer = gtk_cell_renderer_text_new();
+        column = gtk_tree_view_column_new_with_attributes(
+                _("# POIs"), renderer, "text", CAT_POI_CNT, NULL);
+        gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
+
+        gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 300);
+
+        g_signal_connect(G_OBJECT(btn_edit), "clicked",
+                G_CALLBACK(category_edit), tree_view);
+
+        g_signal_connect(G_OBJECT(btn_add), "clicked",
+                G_CALLBACK(category_add), tree_view);
+    }
+
+    gtk_tree_view_set_model(GTK_TREE_VIEW(tree_view), GTK_TREE_MODEL(store));
+    g_object_unref(G_OBJECT(store));
+
+    gtk_widget_show_all(dialog);
+
+    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
+    {
+        break;
+    }
+
+    gtk_widget_hide(dialog);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+poi_delete(GtkWidget *widget, DeletePOI *dpoi)
+{
+    GtkWidget *confirm;
+    gint i;
+    gchar *buffer;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    buffer = g_strdup_printf("%s\n%s", _("Delete POI?"), dpoi->txt_label);
+    confirm = hildon_note_new_confirmation (GTK_WINDOW(_window), buffer);
+    g_free(buffer);
+    i = gtk_dialog_run (GTK_DIALOG (confirm));
+    gtk_widget_destroy (GTK_WIDGET (confirm));
+
+    if(i == GTK_RESPONSE_OK)
+    {
+        if(SQLITE_OK != sqlite3_bind_int(_stmt_delete_poi, 1, dpoi->id) ||
+           SQLITE_DONE != sqlite3_step(_stmt_delete_poi))
+        {
+            MACRO_BANNER_SHOW_INFO(_window, _("Error deleting POI"));
+        }
+        else
+        {
+            gtk_widget_hide_all(dpoi->dialog);
+            map_force_redraw();
+        }
+        sqlite3_reset(_stmt_delete_poi);
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static void
+poi_populate_categories(GtkListStore *store, gint cat_id,
+        GtkTreeIter *out_active)
+{
+    gboolean has_active = FALSE;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    gtk_list_store_clear(store);
+
+    while(SQLITE_ROW == sqlite3_step(_stmt_selall_cat))
+    {
+        GtkTreeIter iter;
+        gint cid = sqlite3_column_int(_stmt_selall_cat, 0);
+        const gchar *clab = sqlite3_column_text(_stmt_selall_cat, 1);
+
+        gtk_list_store_append(store, &iter);
+        gtk_list_store_set(store, &iter, 0, cid, 1, clab, -1);
+
+        if(cid == cat_id || !has_active)
+        {
+            *out_active = iter;
+            has_active = TRUE;
+        }
+    }
+    sqlite3_reset(_stmt_selall_cat);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+static gboolean
+poi_edit_cat(GtkWidget *widget, PoiCategoryEditInfo *data)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+    if(category_list_dialog())
+    {
+        GtkTreeIter active;
+        poi_populate_categories(GTK_LIST_STORE(gtk_combo_box_get_model(
+                        GTK_COMBO_BOX(data->cmb_category))),
+                data->cat_id, &active);
+        gtk_combo_box_set_active_iter(
+                GTK_COMBO_BOX(data->cmb_category), &active);
+    }
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static GtkWidget*
+poi_create_cat_combo(gint selected_cat_id)
+{
+    GtkWidget *cmb_category;
+    GtkTreeModel *model;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    model = GTK_TREE_MODEL(gtk_list_store_new(2,
+                G_TYPE_INT,      /* Category ID */
+                G_TYPE_STRING)); /* Category Label */
+    cmb_category = gtk_combo_box_new_with_model(model);
+    g_object_unref(model);
+
+    /* Set up the view for the combo box. */
+    {
+        GtkCellRenderer *renderer;
+        GtkTreeIter active;
+        renderer = gtk_cell_renderer_text_new();
+        gtk_cell_layout_pack_start(
+                GTK_CELL_LAYOUT(cmb_category), renderer, TRUE);
+        gtk_cell_layout_set_attributes(
+                GTK_CELL_LAYOUT(cmb_category), renderer, "text", 1, NULL);
+
+        poi_populate_categories(GTK_LIST_STORE(gtk_combo_box_get_model(
+                    GTK_COMBO_BOX(cmb_category))), selected_cat_id,
+                &active);
+        if(selected_cat_id)
+            gtk_combo_box_set_active_iter(GTK_COMBO_BOX(cmb_category),&active);
+    }
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+    return cmb_category;
+}
+
+gboolean
+poi_view_dialog(PoiInfo *poi, gint unitx, gint unity)
+{
+    PoiInfo static_poi;
+    gchar buffer[16];
+    GtkWidget *dialog;
+    GtkWidget *table;
+    GtkWidget *label;
+    GtkWidget *txt_label;
+    GtkWidget *txt_lat;
+    GtkWidget *txt_lon;
+    GtkWidget *cmb_category;
+    GtkWidget *txt_desc;
+    GtkWidget *btn_delete = NULL;
+    GtkWidget *btn_catedit;
+    GtkWidget *hbox;
+    GtkWidget *txt_scroll;
+    GtkTextBuffer *desc_txt;
+    GtkTextIter begin, end;
+    DeletePOI dpoi = {NULL, NULL, 0};
+    PoiCategoryEditInfo pcedit;
+    gboolean is_edit;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    is_edit = poi ? TRUE : FALSE;
+
+    if(is_edit)
+    {
+        dialog = gtk_dialog_new_with_buttons(_("Edit POI"),
+            GTK_WINDOW(_window), GTK_DIALOG_MODAL,
+            GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+            NULL);
+
+        gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
+                btn_delete = gtk_button_new_with_label(_("Delete...")));
+
+        dpoi.dialog = dialog;
+        dpoi.txt_label = g_strdup(poi->label);
+        dpoi.id = poi->poi_id;
+
+        g_signal_connect(G_OBJECT(btn_delete), "clicked",
+                          G_CALLBACK(poi_delete), &dpoi);
+
+        gtk_dialog_add_button(GTK_DIALOG(dialog),
+                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
+    }
+    else
+    {
+        poi = &static_poi;
+
+        if(SQLITE_ROW == sqlite3_step(_stmt_nextlabel_poi))
+            poi->label = g_strdup_printf("Point%06d",
+                    sqlite3_column_int(_stmt_nextlabel_poi, 0));
+        sqlite3_reset(_stmt_nextlabel_poi);
+
+        unit2latlon(unitx, unity, poi->lat, poi->lon);
+
+        poi->poi_id = 0;
+        poi->cat_id = 0;
+        poi->desc = g_strdup("");
+
+        dialog = gtk_dialog_new_with_buttons(_("Add POI"),
+            GTK_WINDOW(_window), GTK_DIALOG_MODAL,
+            GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+            GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+            NULL);
+    }
+
+    /* Set the lat/lon strings. */
+    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+            table = gtk_table_new(6, 4, FALSE), TRUE, TRUE, 0);
+
+    gtk_table_attach(GTK_TABLE(table),
+            label = gtk_label_new(_("Lat")),
+            0, 1, 0, 1, GTK_FILL, 0, 2, 4);
+    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+    gtk_table_attach(GTK_TABLE(table),
+            txt_lat = gtk_entry_new(),
+            1, 2, 0, 1, GTK_FILL, 0, 2, 4);
+
+    gtk_table_attach(GTK_TABLE(table),
+            label = gtk_label_new(_("Lon")),
+            2, 3, 0, 1, GTK_FILL, 0, 2, 4);
+    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+    gtk_table_attach(GTK_TABLE(table),
+            txt_lon = gtk_entry_new(),
+            3, 4, 0, 1, GTK_FILL, 0, 2, 4);
+
+    gtk_table_attach(GTK_TABLE(table),
+            label = gtk_label_new(_("Label")),
+            0, 1, 1, 2, GTK_FILL, 0, 2, 4);
+    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+    gtk_table_attach(GTK_TABLE(table),
+            txt_label = gtk_entry_new(),
+            1, 4, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+
+    gtk_table_attach(GTK_TABLE(table),
+            label = gtk_label_new(_("Category")),
+            0, 1, 3, 4, GTK_FILL, 0, 2, 4);
+    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+    gtk_table_attach(GTK_TABLE(table),
+            hbox = gtk_hbox_new(FALSE, 4),
+            1, 4, 3, 4, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+    gtk_box_pack_start(GTK_BOX(hbox),
+            cmb_category = poi_create_cat_combo(poi->cat_id),
+            FALSE, FALSE, 4);
+
+    gtk_box_pack_start(GTK_BOX(hbox),
+            btn_catedit = gtk_button_new_with_label(_("Edit Categories...")),
+            FALSE, FALSE, 4);
+
+    gtk_table_attach(GTK_TABLE(table),
+            label = gtk_label_new(_("Description")),
+            0, 1, 5, 6, GTK_FILL, 0, 2, 4);
+    gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+
+    txt_scroll = gtk_scrolled_window_new(NULL, NULL);
+    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(txt_scroll),
+                                   GTK_SHADOW_IN);
+    gtk_table_attach(GTK_TABLE(table),
+            txt_scroll,
+            1, 4, 5, 6, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+
+    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(txt_scroll),
+                                 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+
+    txt_desc = gtk_text_view_new ();
+    gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt_desc), GTK_WRAP_WORD);
+
+    gtk_container_add(GTK_CONTAINER(txt_scroll), txt_desc);
+    gtk_widget_set_size_request(GTK_WIDGET(txt_scroll), 400, 60);
+
+    desc_txt = gtk_text_view_get_buffer (GTK_TEXT_VIEW (txt_desc));
+
+    /* Lat/Lon */
+    snprintf(buffer, sizeof(buffer), "%.06f", poi->lat);
+    gtk_entry_set_text(GTK_ENTRY(txt_lat), buffer);
+    snprintf(buffer, sizeof(buffer), "%.06f", poi->lon);
+    gtk_entry_set_text(GTK_ENTRY(txt_lon), buffer);
+
+    /* label */
+    gtk_entry_set_text(GTK_ENTRY(txt_label), poi->label);
+
+    /* poi_desc */
+    gtk_text_buffer_set_text(desc_txt, poi->desc, -1);
+
+    /* Connect Signals */
+    pcedit.cmb_category = cmb_category;
+    pcedit.cat_id = poi->cat_id;
+    g_signal_connect(G_OBJECT(btn_catedit), "clicked",
+            G_CALLBACK(poi_edit_cat), &pcedit);
+    gtk_widget_show_all(dialog);
+
+    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
+    {
+        GtkTreeIter iter;
+        const gchar *text;
+        gchar *error_check;
+
+        text = gtk_entry_get_text(GTK_ENTRY(txt_lat));
+        poi->lat = strdmstod(text, &error_check);
+        if(text == error_check || poi->lat < -90. || poi->lat > 90.) {
+            popup_error(dialog, _("Invalid Latitude"));
+            continue;
+        }
+
+        text = gtk_entry_get_text(GTK_ENTRY(txt_lon));
+        poi->lon = strdmstod(text, &error_check);
+        if(text == error_check || poi->lon < -180. || poi->lon > 180.) {
+            popup_error(dialog, _("Invalid Longitude"));
+            continue;
+        }
+
+        if(strlen(gtk_entry_get_text(GTK_ENTRY(txt_label))))
+        {
+            if(poi->label)
+                g_free(poi->label);
+            poi->label = g_strdup(gtk_entry_get_text(GTK_ENTRY(txt_label)));
+        }
+        else
+        {
+            popup_error(dialog, _("Please specify a name."));
+            continue;
+        }
+
+        if(!gtk_combo_box_get_active_iter(
+                GTK_COMBO_BOX(cmb_category), &iter))
+        {
+            popup_error(dialog, _("Please specify a category."));
+            continue;
+        }
+
+        gtk_text_buffer_get_iter_at_offset(desc_txt, &begin,0 );
+        gtk_text_buffer_get_end_iter (desc_txt, &end);
+        if(poi->desc)
+            g_free(poi->desc);
+        poi->desc = gtk_text_buffer_get_text(desc_txt, &begin, &end, TRUE);
+
+        if(poi->clabel)
+            g_free(poi->clabel);
+        gtk_tree_model_get(
+                gtk_combo_box_get_model(GTK_COMBO_BOX(cmb_category)), &iter,
+                0, &poi->cat_id,
+                1, &poi->clabel,
+                -1);
+
+        if(is_edit)
+        {
+            /* edit poi */
+            if(SQLITE_OK != sqlite3_bind_double(
+                        _stmt_update_poi, 1, poi->lat) ||
+               SQLITE_OK != sqlite3_bind_double(
+                   _stmt_update_poi, 2, poi->lon) ||
+               SQLITE_OK != sqlite3_bind_text(_stmt_update_poi, 3, poi->label,
+                        -1, SQLITE_STATIC) ||
+               SQLITE_OK != sqlite3_bind_text(_stmt_update_poi, 4, poi->desc,
+                   -1, g_free) ||
+               SQLITE_OK != sqlite3_bind_int(
+                   _stmt_update_poi, 5, poi->cat_id) ||
+               SQLITE_OK != sqlite3_bind_int(
+                   _stmt_update_poi, 6, poi->poi_id) ||
+               SQLITE_DONE != sqlite3_step(_stmt_update_poi))
+            {
+                MACRO_BANNER_SHOW_INFO(_window, _("Error updating POI"));
+            }
+            else
+            {
+                map_force_redraw();
+            }
+            sqlite3_reset(_stmt_update_poi);
+        }
+        else
+        {
+            /* add poi */
+            if(SQLITE_OK != sqlite3_bind_double(_stmt_insert_poi, 1, poi->lat)
+            || SQLITE_OK != sqlite3_bind_double(_stmt_insert_poi, 2, poi->lon)
+            || SQLITE_OK != sqlite3_bind_text(_stmt_insert_poi, 3, poi->label,
+                   -1, g_free)
+            || SQLITE_OK != sqlite3_bind_text(_stmt_insert_poi, 4, poi->desc,
+                   -1, g_free)
+            || SQLITE_OK != sqlite3_bind_int(_stmt_insert_poi, 5, poi->cat_id)
+            || SQLITE_DONE != sqlite3_step(_stmt_insert_poi))
+            {
+                MACRO_BANNER_SHOW_INFO(_window, _("Error adding POI"));
+            }
+            else
+            {
+                MACRO_MAP_RENDER_DATA();
+            }
+            sqlite3_reset(_stmt_insert_poi);
+            g_free(poi->label);
+            g_free(poi->desc);
+        }
+        break;
+    }
+
+    g_free(dpoi.txt_label);
+
+    map_force_redraw();
+
+    gtk_widget_destroy(dialog);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gint
+poi_list_insert(GList *poi_list, GtkComboBox *cmb_category)
+{
+    gint default_cat_id;
+    gchar *default_cat_label;
+    gint num_inserts = 0;
+    GList *curr;
+    GtkTreeIter iter;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    /* Get defaults from the given GtkComboBox */
+    if(!gtk_combo_box_get_active_iter(
+            GTK_COMBO_BOX(cmb_category), &iter))
+    {
+        vprintf("%s(): return 0\n", __PRETTY_FUNCTION__);
+        return 0;
+    }
+    gtk_tree_model_get(
+            gtk_combo_box_get_model(GTK_COMBO_BOX(cmb_category)),
+            &iter,
+            0, &default_cat_id,
+            1, &default_cat_label,
+            -1);
+
+    /* Iterate through the data model and import as desired. */
+    for(curr = poi_list; curr; )
+    {
+        PoiInfo *poi = curr->data;
+        if(
+        (    SQLITE_OK != sqlite3_bind_double(_stmt_insert_poi, 1, poi->lat)
+          || SQLITE_OK != sqlite3_bind_double(_stmt_insert_poi, 2, poi->lon)
+          || SQLITE_OK != sqlite3_bind_text(_stmt_insert_poi, 3, poi->label,
+             -1, SQLITE_STATIC)
+          || SQLITE_OK != sqlite3_bind_text(_stmt_insert_poi, 4, poi->desc,
+             -1, SQLITE_STATIC)
+          || SQLITE_OK != sqlite3_bind_int(_stmt_insert_poi, 5,
+              poi->cat_id = default_cat_id)
+          || SQLITE_DONE != sqlite3_step(_stmt_insert_poi)
+        ))
+        {
+            /* Failure. */
+            GList *tmp = curr->next;
+            if(poi->label)
+                g_free(poi->label);
+            if(poi->desc)
+                g_free(poi->desc);
+            g_slice_free(PoiInfo, poi);
+            poi_list = g_list_delete_link(poi_list, curr);
+            curr = tmp;
+        }
+        else
+        {
+            /* Success. */
+            ++num_inserts;
+            if(default_cat_label)
+                poi->clabel = g_strdup(default_cat_label);
+            poi->poi_id = sqlite3_last_insert_rowid(_poi_db);
+            curr = curr->next;
+        }
+        sqlite3_reset(_stmt_insert_poi);
+    }
+
+    if(num_inserts)
+    {
+        gchar buffer[BUFFER_SIZE];
+        map_force_redraw();
+        snprintf(buffer, sizeof(buffer), "%d %s", num_inserts,
+           _("POIs were added to the POI database.  The following screen will "
+               "allow you to modify or delete any of the new POIs."));
+        popup_error(_window, buffer);
+    }
+    else
+    {
+        popup_error(_window, _("No POIs were found."));
+    }
+
+    if(default_cat_label)
+        g_free(default_cat_label);
+
+    vprintf("%s(): return %d\n", __PRETTY_FUNCTION__, num_inserts);
+    return num_inserts;
+}
+
+static void
+poi_list_free(GList *poi_list)
+{
+    GList *curr;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    for(curr = poi_list; curr; curr = curr->next)
+    {
+        PoiInfo *poi_info = curr->data;
+        if(poi_info)
+        {
+            if(poi_info->label)
+                g_free(poi_info->label);
+            if(poi_info->desc)
+                g_free(poi_info->desc);
+            if(poi_info->clabel)
+                g_free(poi_info->clabel);
+            g_slice_free(PoiInfo, poi_info);
+        }
+    }
+
+    g_list_free(poi_list);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+static void
+poi_list_bearing_cell_data_func(
+        GtkTreeViewColumn *tree_column,
+        GtkCellRenderer *cell,
+        GtkTreeModel *tree_model,
+        GtkTreeIter *iter)
+{
+    gchar buffer[80];
+    gfloat f;
+    vprintf("%s()\n", __PRETTY_FUNCTION__);
+
+    gtk_tree_model_get(tree_model, iter, POI_BEARING, &f, -1);
+    snprintf(buffer, sizeof(buffer), "%.1f", f);
+    g_object_set(cell, "text", buffer, NULL);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+static void
+poi_list_distance_cell_data_func(
+        GtkTreeViewColumn *tree_column,
+        GtkCellRenderer *cell,
+        GtkTreeModel *tree_model,
+        GtkTreeIter *iter)
+{
+    gchar buffer[80];
+    gfloat f;
+    vprintf("%s()\n", __PRETTY_FUNCTION__);
+
+    gtk_tree_model_get(tree_model, iter, POI_DISTANCE, &f, -1);
+    snprintf(buffer, sizeof(buffer), "%.2f", f);
+    g_object_set(cell, "text", buffer, NULL);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+static gboolean
+poi_list_row_selected(GtkCellRendererToggle *renderer,
+        gchar *path_string, GtkTreeModel *tree_model)
+{
+    GtkTreeIter iter;
+    vprintf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(gtk_tree_model_get_iter_from_string(tree_model, &iter, path_string))
+    {
+        gboolean old_value;
+        gtk_tree_model_get(tree_model, &iter, POI_SELECTED, &old_value, -1);
+        gtk_list_store_set(GTK_LIST_STORE(tree_model), &iter,
+                POI_SELECTED, !old_value,
+                -1);
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+poi_list_set_category(GtkWidget *widget, PoiListInfo *pli)
+{
+    GtkWidget *dialog;
+    GtkWidget *hbox;
+    GtkWidget *label;
+    GtkWidget *cmb_category;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    dialog = gtk_dialog_new_with_buttons(_("Set Category..."),
+            GTK_WINDOW(pli->dialog2), GTK_DIALOG_MODAL,
+            GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+            GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+            NULL);
+
+    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+            hbox = gtk_hbox_new(FALSE, 4), FALSE, FALSE, 4);
+
+    gtk_box_pack_start(GTK_BOX(hbox),
+            label = gtk_label_new(_("Category")),
+            FALSE, FALSE, 0);
+
+    gtk_box_pack_start(GTK_BOX(hbox),
+            cmb_category = poi_create_cat_combo(0),
+            FALSE, FALSE, 4);
+
+    gtk_widget_show_all(dialog);
+
+    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
+    {
+        GtkTreeIter iter;
+        GtkListStore *store;
+        gint cat_id;
+        const gchar *cat_label;
+
+        /* Get the text of the chosen category. */
+        if(!gtk_combo_box_get_active_iter(
+                GTK_COMBO_BOX(cmb_category), &iter))
+        {
+            popup_error(dialog, _("Please specify a category."));
+            continue;
+        }
+
+        gtk_tree_model_get(
+                gtk_combo_box_get_model(GTK_COMBO_BOX(cmb_category)),
+                &iter,
+                0, &cat_id,
+                1, &cat_label,
+                -1);
+
+        /* Iterate through the data store and categorize as desired. */
+        store = GTK_LIST_STORE(gtk_tree_view_get_model(
+                    GTK_TREE_VIEW(pli->tree_view)));
+        if(gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter)) do
+        {
+            PoiInfo poi;
+            gboolean selected;
+
+            memset(&poi, 0, sizeof(poi));
+
+            gtk_tree_model_get(GTK_TREE_MODEL(store), &iter,
+                    POI_SELECTED, &selected,
+                    POI_POIID, &(poi.poi_id),
+                    POI_LAT, &(poi.lat),
+                    POI_LON, &(poi.lon),
+                    POI_LABEL, &(poi.label),
+                    POI_DESC, &(poi.desc),
+                    -1);
+
+            if(selected)
+            {
+                gtk_list_store_set(store, &iter,
+                    POI_CATID, cat_id,
+                    POI_CLABEL, cat_label,
+                    -1);
+                /* edit poi */
+                if(SQLITE_OK != sqlite3_bind_double(
+                            _stmt_update_poi, 1, poi.lat) ||
+                   SQLITE_OK != sqlite3_bind_double(
+                       _stmt_update_poi, 2, poi.lon) ||
+                   SQLITE_OK != sqlite3_bind_text(_stmt_update_poi,
+                       3, poi.label, -1, SQLITE_STATIC) ||
+                   SQLITE_OK != sqlite3_bind_text(_stmt_update_poi,
+                       4, poi.desc, -1, SQLITE_STATIC) ||
+                   SQLITE_OK != sqlite3_bind_int(
+                       _stmt_update_poi, 5, cat_id) ||
+                   SQLITE_OK != sqlite3_bind_int(
+                       _stmt_update_poi, 6, poi.poi_id) ||
+                   SQLITE_DONE != sqlite3_step(_stmt_update_poi))
+                {
+                    MACRO_BANNER_SHOW_INFO(_window, _("Error updating POI"));
+                }
+                sqlite3_reset(_stmt_update_poi);
+            }
+        } while(gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter));
+
+        break;
+    }
+
+    map_force_redraw();
+    gtk_widget_destroy(dialog);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+poi_list_select_all(GtkTreeViewColumn *column, PoiListInfo *pli)
+{
+    GtkTreeIter iter;
+    GtkListStore *store;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    /* Iterate through the data store and select as desired. */
+    store = GTK_LIST_STORE(gtk_tree_view_get_model(
+                GTK_TREE_VIEW(pli->tree_view)));
+    if(gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter)) do
+    {
+        gtk_list_store_set(store, &iter,
+            POI_SELECTED, pli->select_all,
+            -1);
+    } while(gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter));
+
+    pli->select_all = !pli->select_all;
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+poi_list_view(GtkWidget *widget, PoiListInfo *pli)
+{
+    GtkTreeIter iter;
+    GtkTreeSelection *selection;
+    GtkListStore *store;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(pli->tree_view));
+    store = GTK_LIST_STORE(gtk_tree_view_get_model(
+                GTK_TREE_VIEW(pli->tree_view)));
+
+    /* Iterate through the data store and import as desired. */
+    if(gtk_tree_selection_get_selected(selection, NULL, &iter))
+    {
+        PoiInfo poi;
+        memset(&poi, 0, sizeof(poi));
+
+        gtk_tree_model_get(GTK_TREE_MODEL(store), &iter,
+                POI_POIID, &(poi.poi_id),
+                POI_CATID, &(poi.cat_id),
+                POI_LAT, &(poi.lat),
+                POI_LON, &(poi.lon),
+                POI_LABEL, &(poi.label),
+                POI_DESC, &(poi.desc),
+                POI_CLABEL, &(poi.clabel),
+                -1);
+
+        if(poi_view_dialog(&poi, 0, 0))
+        {
+            gtk_list_store_set(store, &iter,
+                    POI_POIID, poi.poi_id,
+                    POI_CATID, poi.cat_id,
+                    POI_LAT, poi.lat,
+                    POI_LON, poi.lon,
+                    POI_LABEL, poi.label,
+                    POI_DESC, poi.desc,
+                    POI_CLABEL, poi.clabel,
+                    -1);
+        }
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static void
+poi_list_row_activated(GtkTreeView *tree_view, GtkTreePath *path,
+        GtkTreeViewColumn *column, PoiListInfo *pli)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(column != pli->select_column)
+        poi_list_view(GTK_WIDGET(tree_view), pli);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+}
+
+static GtkWidget*
+poi_list_create_tree_view(PoiListInfo *pli, gint unitx, gint unity,
+        GList *poi_list)
+{
+    GList *curr;
+    GtkWidget *tree_view;
+    GtkCellRenderer *renderer;
+    GtkTreeViewColumn *column;
+    GtkListStore *store;
+    GtkTreeIter iter;
+    gfloat src_lat, src_lon;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    unit2latlon(unitx, unity, src_lat, src_lon);
+
+    store = gtk_list_store_new(POI_NUM_COLUMNS,
+                               G_TYPE_BOOLEAN,/* Selected */
+                               G_TYPE_INT,    /* POI ID */
+                               G_TYPE_INT,    /* Category ID */
+                               G_TYPE_FLOAT,  /* Latitude */
+                               G_TYPE_FLOAT,  /* Longitude */
+                               G_TYPE_STRING, /* Lat/Lon */
+                               G_TYPE_FLOAT,  /* Bearing */
+                               G_TYPE_FLOAT,  /* Distance */
+                               G_TYPE_STRING, /* POI Label */
+                               G_TYPE_STRING, /* POI Desc. */
+                               G_TYPE_STRING);/* Category Label */
+
+    tree_view = gtk_tree_view_new();
+
+    g_object_set(G_OBJECT(tree_view), "allow-checkbox-mode", FALSE, NULL);
+
+    gtk_tree_selection_set_mode(
+            gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view)),
+            GTK_SELECTION_SINGLE);
+    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree_view), TRUE);
+
+    renderer = gtk_cell_renderer_toggle_new();
+    gtk_cell_renderer_toggle_set_active(GTK_CELL_RENDERER_TOGGLE(renderer),
+            TRUE);
+    g_signal_connect(G_OBJECT(renderer), "toggled",
+            G_CALLBACK(poi_list_row_selected), store);
+    pli->select_column = gtk_tree_view_column_new_with_attributes(
+            "*", renderer, "active", POI_SELECTED, NULL);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), pli->select_column);
+    gtk_tree_view_column_set_clickable(pli->select_column, TRUE);
+    pli->select_all = FALSE;
+    g_signal_connect(G_OBJECT(pli->select_column), "clicked",
+            G_CALLBACK(poi_list_select_all), pli);
+
+    renderer = gtk_cell_renderer_combo_new();
+    column = gtk_tree_view_column_new_with_attributes(
+            _("Category"), renderer, "text", POI_CLABEL, NULL);
+    gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_GROW_ONLY);
+    gtk_tree_view_column_set_sort_column_id(column, POI_CLABEL);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
+
+    renderer = gtk_cell_renderer_text_new();
+    g_object_set(renderer, "xalign", 1.f, NULL);
+    column = gtk_tree_view_column_new_with_attributes(
+            _("Dist."), renderer, "text", POI_DISTANCE, NULL);
+    gtk_tree_view_column_set_cell_data_func(column, renderer,
+            (GtkTreeCellDataFunc)poi_list_distance_cell_data_func, NULL, NULL);
+    gtk_tree_view_column_set_sort_column_id(column, POI_DISTANCE);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
+
+    renderer = gtk_cell_renderer_text_new();
+    g_object_set(renderer, "xalign", 1.f, NULL);
+    column = gtk_tree_view_column_new_with_attributes(
+            _("Bear."), renderer, "text", POI_BEARING, NULL);
+    gtk_tree_view_column_set_cell_data_func(column, renderer,
+            (GtkTreeCellDataFunc)poi_list_bearing_cell_data_func, NULL, NULL);
+    gtk_tree_view_column_set_sort_column_id(column, POI_BEARING);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
+
+    renderer = gtk_cell_renderer_text_new();
+    column = gtk_tree_view_column_new_with_attributes(
+            _("Label"), renderer, "text", POI_LABEL, NULL);
+    gtk_tree_view_column_set_sort_column_id(column, POI_LABEL);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
+
+    for(curr = poi_list; curr; curr = curr->next)
+    {
+        PoiInfo *poi_info = curr->data;
+        gchar tmp1[LL_FMT_LEN], tmp2[LL_FMT_LEN];
+
+        printf("poi: (%f, %f, %s, %s)\n",
+                poi_info->lat, poi_info->lon,
+                poi_info->label, poi_info->desc);
+
+        lat_format(poi_info->lat, tmp1);
+        lon_format(poi_info->lon, tmp2);
+
+        gtk_list_store_append(store, &iter);
+        gtk_list_store_set(store, &iter,
+                POI_SELECTED, TRUE,
+                POI_POIID, poi_info->poi_id,
+                POI_LAT, poi_info->lat,
+                POI_LON, poi_info->lon,
+                POI_BEARING, calculate_bearing(src_lat, src_lon,
+                    poi_info->lat, poi_info->lon),
+                POI_DISTANCE, calculate_distance(src_lat,src_lon,
+                    poi_info->lat, poi_info->lon) * UNITS_CONVERT[_units],
+                POI_LABEL, poi_info->label,
+                POI_DESC, poi_info->desc,
+                POI_CATID, poi_info->cat_id,
+                POI_CLABEL, poi_info->clabel,
+                -1);
+    }
+
+    g_signal_connect(G_OBJECT(tree_view), "row-activated",
+            G_CALLBACK(poi_list_row_activated), pli);
+
+    gtk_tree_view_set_model(GTK_TREE_VIEW(tree_view), GTK_TREE_MODEL(store));
+    g_object_unref(G_OBJECT(store));
+
+    printf("%s(): return %p\n", __PRETTY_FUNCTION__, tree_view);
+    return tree_view;
+}
+
+static gboolean
+poi_list_goto(GtkWidget *widget, PoiListInfo *pli)
+{
+    GtkTreeIter iter;
+    GtkTreeSelection *selection;
+    GtkListStore *store;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(pli->tree_view));
+    store = GTK_LIST_STORE(gtk_tree_view_get_model(
+                GTK_TREE_VIEW(pli->tree_view)));
+
+    /* Iterate through the data store and import as desired. */
+    if(gtk_tree_selection_get_selected(selection, NULL, &iter))
+    {
+        gfloat lat, lon;
+        Point unit;
+
+        gtk_tree_model_get(GTK_TREE_MODEL(store), &iter,
+                POI_LAT, &lat,
+                POI_LON, &lon,
+                -1);
+
+        latlon2unit(lat, lon, unit.unitx, unit.unity);
+
+        if(_center_mode > 0)
+            gtk_check_menu_item_set_active(
+                    GTK_CHECK_MENU_ITEM(_menu_view_ac_none_item), TRUE);
+
+        map_center_unit(unit);
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+poi_list_delete(GtkWidget *widget, PoiListInfo *pli)
+{
+    GtkWidget *confirm;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    confirm = hildon_note_new_confirmation(
+            GTK_WINDOW(pli->dialog2), _("Delete selected POI?"));
+
+    if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm)))
+    {
+        GtkTreeIter iter;
+        GtkListStore *store;
+        gboolean already_next;
+        gboolean must_iterate;;
+
+        /* Iterate through the data store and import as desired. */
+        store = GTK_LIST_STORE(gtk_tree_view_get_model(
+                    GTK_TREE_VIEW(pli->tree_view)));
+        if(gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter)) do
+        {
+            gboolean selected;
+            must_iterate = TRUE;
+            already_next = FALSE;
+            gint poi_id;
+            gtk_tree_model_get(GTK_TREE_MODEL(store), &iter,
+                POI_SELECTED, &selected,
+                POI_POIID, &poi_id,
+                -1);
+            if(selected)
+            {
+                /* Delete POI. */
+                if(SQLITE_OK != sqlite3_bind_int(_stmt_delete_poi, 1, poi_id)
+                || SQLITE_DONE != sqlite3_step(_stmt_delete_poi))
+                {
+                    MACRO_BANNER_SHOW_INFO(_window, _("Error deleting POI"));
+                }
+                else
+                {
+                    already_next = gtk_list_store_remove(store, &iter);
+                    must_iterate = FALSE;
+                }
+                sqlite3_reset(_stmt_delete_poi);
+            }
+        } while(already_next || (must_iterate
+                && gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter)));
+    }
+
+    map_force_redraw();
+
+    gtk_widget_destroy(confirm);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+poi_list_export_gpx(GtkWidget *widget, PoiListInfo *pli)
+{
+    GnomeVFSHandle *handle;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(display_open_file(pli->dialog2, NULL, &handle, NULL, NULL, NULL,
+                    GTK_FILE_CHOOSER_ACTION_SAVE))
+    {
+        gint num_exported = gpx_poi_write(
+               gtk_tree_view_get_model(GTK_TREE_VIEW(pli->tree_view)), handle);
+        if(num_exported >= 0)
+        {
+            gchar buffer[80];
+            snprintf(buffer, sizeof(buffer), "%d %s\n", num_exported,
+                    _("POIs Exported"));
+            MACRO_BANNER_SHOW_INFO(_window, buffer);
+        }
+        else
+            popup_error(_window, _("Error writing GPX file."));
+        gnome_vfs_close(handle);
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+poi_list_manage_checks(GtkWidget *widget, PoiListInfo *pli)
+{
+    GtkWidget *btn_category;
+    GtkWidget *btn_delete;
+    GtkWidget *btn_export_gpx;
+
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    pli->dialog2 = gtk_dialog_new_with_buttons(_("Checked POI Actions..."),
+            GTK_WINDOW(pli->dialog), GTK_DIALOG_MODAL,
+            NULL);
+
+    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(pli->dialog2)->vbox),
+            gtk_label_new(_("Select an operation to perform\n"
+                            "on the POIs that you checked\n"
+                            "in the POI list.")),
+                FALSE, FALSE, 4);
+
+    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(pli->dialog2)->vbox),
+            btn_category = gtk_button_new_with_label(_("Set Category...")),
+                FALSE, FALSE, 4);
+
+    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(pli->dialog2)->vbox),
+            btn_delete = gtk_button_new_with_label(_("Delete...")),
+                FALSE, FALSE, 4);
+
+    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(pli->dialog2)->vbox),
+            btn_export_gpx = gtk_button_new_with_label(
+                _("Export to GPX...")),
+                FALSE, FALSE, 4);
+
+    gtk_dialog_add_button(GTK_DIALOG(pli->dialog2),
+            GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT);
+
+    g_signal_connect(G_OBJECT(btn_category), "clicked",
+            G_CALLBACK(poi_list_set_category), pli);
+
+    g_signal_connect(G_OBJECT(btn_delete), "clicked",
+            G_CALLBACK(poi_list_delete), pli);
+
+    g_signal_connect(G_OBJECT(btn_export_gpx), "clicked",
+            G_CALLBACK(poi_list_export_gpx), pli);
+
+    gtk_widget_show_all(pli->dialog2);
+
+    gtk_dialog_run(GTK_DIALOG(pli->dialog2));
+
+    gtk_widget_destroy(pli->dialog2);
+    pli->dialog2 = NULL;
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+poi_list_dialog(gint unitx, gint unity, GList *poi_list)
+{
+    PoiListInfo pli;
+    GtkWidget *scroller;
+    GtkWidget *btn_goto;
+    GtkWidget *btn_edit;
+    GtkWidget *btn_manage_checks;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    /* Create category table for mapping category names to IDs. */
+    pli.tree_view = poi_list_create_tree_view(&pli, unitx, unity, poi_list);
+
+    pli.dialog = gtk_dialog_new_with_buttons(_("POI List"),
+        GTK_WINDOW(_window), GTK_DIALOG_MODAL,
+            NULL);
+
+    /* Enable the help button. */
+    ossohelp_dialog_help_enable(
+            GTK_DIALOG(pli.dialog), HELP_ID_POILIST, _osso);
+
+    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(pli.dialog)->action_area),
+            btn_goto = gtk_button_new_with_label(_("Go to")));
+
+    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(pli.dialog)->action_area),
+            btn_edit = gtk_button_new_with_label(_("Edit...")));
+
+    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(pli.dialog)->action_area),
+            btn_manage_checks = gtk_button_new_with_label(
+                _("Checked POI Actions...")));
+
+    gtk_dialog_add_button(GTK_DIALOG(pli.dialog),
+            GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT);
+
+    gtk_window_set_default_size(GTK_WINDOW(pli.dialog), 500, 400);
+
+    scroller = gtk_scrolled_window_new (NULL, NULL);
+    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroller),
+            GTK_SHADOW_ETCHED_IN);
+    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroller),
+            GTK_POLICY_NEVER,
+            GTK_POLICY_AUTOMATIC);
+    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(pli.dialog)->vbox),
+            scroller, TRUE, TRUE, 0);
+
+    gtk_container_add(GTK_CONTAINER(scroller), pli.tree_view);
+
+    g_signal_connect(G_OBJECT(btn_goto), "clicked",
+            G_CALLBACK(poi_list_goto), &pli);
+
+    g_signal_connect(G_OBJECT(btn_edit), "clicked",
+            G_CALLBACK(poi_list_view), &pli);
+
+    g_signal_connect(G_OBJECT(btn_manage_checks), "clicked",
+            G_CALLBACK(poi_list_manage_checks), &pli);
+
+    gtk_widget_show_all(pli.dialog);
+
+    GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(pli.dialog));
+
+    map_force_redraw();
+
+    gtk_widget_destroy(pli.dialog);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+gboolean
+poi_import_dialog(gint unitx, gint unity)
+{
+    GtkWidget *dialog = NULL;
+    gboolean success = FALSE;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    dialog = hildon_file_chooser_dialog_new(GTK_WINDOW(_window),
+            GTK_FILE_CHOOSER_ACTION_OPEN);
+
+    gtk_widget_show_all(dialog);
+
+    while(!success && gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
+    {
+        gchar *file_uri_str = NULL;
+        gchar *bytes = NULL;
+        gint size;
+        GnomeVFSResult vfs_result;
+        GList *poi_list = NULL;
+
+        file_uri_str = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(dialog));
+
+        /* Parse the given file as GPX. */
+        if(GNOME_VFS_OK != (vfs_result = gnome_vfs_read_entire_file(
+                        file_uri_str, &size, &bytes)))
+        {
+            popup_error(dialog, gnome_vfs_result_to_string(vfs_result));
+        }
+        else if(gpx_poi_parse(bytes, size, &poi_list))
+        {
+            static GtkWidget *cat_dialog = NULL;
+            static GtkWidget *cmb_category = NULL;
+
+            if(!cat_dialog)
+            {
+                GtkWidget *hbox;
+                GtkWidget *label;
+                cat_dialog = gtk_dialog_new_with_buttons(_("Default Category"),
+                        GTK_WINDOW(dialog), GTK_DIALOG_MODAL,
+                        GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+                        GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+                        NULL);
+
+                gtk_box_pack_start(GTK_BOX(GTK_DIALOG(cat_dialog)->vbox),
+                        hbox = gtk_hbox_new(FALSE, 4), FALSE, FALSE, 4);
+
+                gtk_box_pack_start(GTK_BOX(hbox),
+                        label = gtk_label_new(_("Category")),
+                        FALSE, FALSE, 0);
+
+                gtk_box_pack_start(GTK_BOX(hbox),
+                        cmb_category = poi_create_cat_combo(0),
+                        FALSE, FALSE, 4);
+            }
+
+            gtk_widget_show_all(cat_dialog);
+
+            while(GTK_RESPONSE_ACCEPT ==gtk_dialog_run(GTK_DIALOG(cat_dialog)))
+            {
+                if(gtk_combo_box_get_active(GTK_COMBO_BOX(cmb_category)) == -1)
+                {
+                    popup_error(dialog,
+                            _("Please specify a default category."));
+                    continue;
+                }
+
+                /* Insert the POIs into the database. */
+                gint num_inserts = poi_list_insert(poi_list,
+                        GTK_COMBO_BOX(cmb_category));
+
+                if(num_inserts)
+                {
+                    /* Hide the dialogs. */
+                    gtk_widget_hide(cat_dialog);
+                    gtk_widget_hide(dialog);
+
+                    /* Create a new dialog with the results. */
+                    poi_list_dialog(unitx, unity, poi_list);
+                    success = TRUE;
+                }
+                break;
+            }
+
+            gtk_widget_hide(cat_dialog);
+
+            poi_list_free(poi_list);
+        }
+        else
+            popup_error(dialog, _("Error parsing GPX file."));
+
+        g_free(file_uri_str);
+        g_free(bytes);
+    }
+
+    /* Hide the dialog. */
+    gtk_widget_destroy(dialog);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return success;
+}
+
+static gboolean
+poi_download_cat_selected(GtkComboBox *cmb_category, GtkEntry *txt_query)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(!*gtk_entry_get_text(txt_query))
+    {
+        /* Query is empty - set it with the name of the category. */
+        GtkTreeIter iter;
+        if(gtk_combo_box_get_active_iter(GTK_COMBO_BOX(cmb_category), &iter))
+        {
+            gchar *category;
+
+            gtk_tree_model_get(
+                    gtk_combo_box_get_model(GTK_COMBO_BOX(cmb_category)), &iter,
+                    1, &category,
+                    -1);
+
+            gtk_entry_set_text(txt_query, category);
+        }
+    }
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+
+static gboolean
+origin_type_selected(GtkWidget *toggle, OriginToggleInfo *oti)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle)))
+        gtk_widget_set_sensitive(oti->txt_origin, toggle == oti->rad_use_text);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+gboolean
+poi_download_dialog(gint unitx, gint unity)
+{
+    static GtkWidget *dialog = NULL;
+    static GtkWidget *hbox = NULL;
+    static GtkWidget *table = NULL;
+    static GtkWidget *table2 = NULL;
+    static GtkWidget *label = NULL;
+    static GtkWidget *num_page = NULL;
+    static GtkWidget *txt_source_url = NULL;
+    static OriginToggleInfo oti;
+    static GtkWidget *cmb_category;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    conic_recommend_connected();
+
+    if(!dialog)
+    {
+        GtkEntryCompletion *origin_comp;
+
+        dialog = gtk_dialog_new_with_buttons(_("Download POIs"),
+                GTK_WINDOW(_window), GTK_DIALOG_MODAL,
+                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+                NULL);
+
+        /* Enable the help button. */
+        ossohelp_dialog_help_enable(
+                GTK_DIALOG(dialog), HELP_ID_DOWNPOI, _osso);
+
+        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+                table = gtk_table_new(4, 4, FALSE), TRUE, TRUE, 0);
+
+        /* Source URL. */
+        gtk_table_attach(GTK_TABLE(table),
+                hbox = gtk_hbox_new(FALSE, 4),
+                0, 4, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+        gtk_box_pack_start(GTK_BOX(hbox),
+                label = gtk_label_new(_("Source URL")), FALSE, TRUE, 4);
+        gtk_box_pack_start(GTK_BOX(hbox),
+                txt_source_url = gtk_entry_new(), TRUE, TRUE, 4);
+
+        /* Auto. */
+        gtk_table_attach(GTK_TABLE(table),
+                oti.rad_use_gps = gtk_radio_button_new_with_label(NULL,
+                    _("Use GPS Location")),
+                0, 1, 1, 2, GTK_FILL, 0, 2, 4);
+
+        /* Use End of Route. */
+        gtk_table_attach(GTK_TABLE(table),
+               oti.rad_use_route = gtk_radio_button_new_with_label_from_widget(
+                   GTK_RADIO_BUTTON(oti.rad_use_gps), _("Use End of Route")),
+               0, 1, 2, 3, GTK_FILL, 0, 2, 4);
+
+
+        gtk_table_attach(GTK_TABLE(table),
+                gtk_vseparator_new(),
+                1, 2, 1, 3, GTK_FILL, GTK_FILL, 2,4);
+
+        /* Category. */
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Category")),
+                2, 3, 1, 2, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                cmb_category = poi_create_cat_combo(0),
+                3, 4, 1, 2, GTK_FILL, 0, 2, 4);
+
+        /* Page. */
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Page")),
+                2, 3, 2, 3, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                num_page = hildon_number_editor_new(1, 999),
+                3, 4, 2, 3, GTK_FILL, 0, 2, 4);
+
+
+        /* Another table for the Origin and Query. */
+        gtk_table_attach(GTK_TABLE(table),
+                table2 = gtk_table_new(2, 2, FALSE),
+                0, 4, 3, 4, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+
+        /* Origin. */
+        gtk_table_attach(GTK_TABLE(table2),
+                oti.rad_use_text = gtk_radio_button_new_with_label_from_widget(
+                    GTK_RADIO_BUTTON(oti.rad_use_gps), _("Origin")),
+                0, 1, 0, 1, GTK_FILL, 0, 2, 4);
+        gtk_table_attach(GTK_TABLE(table2),
+                oti.txt_origin = gtk_entry_new(),
+                1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+        gtk_entry_set_width_chars(GTK_ENTRY(oti.txt_origin), 25);
+        g_object_set(G_OBJECT(oti.txt_origin), HILDON_AUTOCAP, FALSE, NULL);
+
+        /* Query. */
+        gtk_table_attach(GTK_TABLE(table2),
+                label = gtk_label_new(_("Query")),
+                0, 1, 1, 2, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table2),
+                oti.txt_query = gtk_entry_new(),
+                1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+        gtk_entry_set_width_chars(GTK_ENTRY(oti.txt_query), 25);
+        g_object_set(G_OBJECT(oti.txt_query), HILDON_AUTOCAP, FALSE, NULL);
+
+        /* Set up auto-completion. */
+        origin_comp = gtk_entry_completion_new();
+        gtk_entry_completion_set_model(origin_comp,GTK_TREE_MODEL(_loc_model));
+        gtk_entry_completion_set_text_column(origin_comp, 0);
+        gtk_entry_set_completion(GTK_ENTRY(oti.txt_origin), origin_comp);
+
+        g_signal_connect(G_OBJECT(oti.rad_use_gps), "toggled",
+                          G_CALLBACK(origin_type_selected), &oti);
+        g_signal_connect(G_OBJECT(oti.rad_use_route), "toggled",
+                          G_CALLBACK(origin_type_selected), &oti);
+        g_signal_connect(G_OBJECT(oti.rad_use_text), "toggled",
+                          G_CALLBACK(origin_type_selected), &oti);
+
+        g_signal_connect(G_OBJECT(cmb_category), "changed",
+                G_CALLBACK(poi_download_cat_selected), oti.txt_query);
+    }
+
+    /* Initialize fields. */
+
+    hildon_number_editor_set_value(HILDON_NUMBER_EDITOR(num_page), 1);
+
+    gtk_entry_set_text(GTK_ENTRY(txt_source_url), _poi_dl_url);
+    if(unity != 0)
+    {
+        gchar buffer[80];
+        gchar strlat[32];
+        gchar strlon[32];
+        gfloat lat, lon;
+
+        unit2latlon(unitx, unity, lat, lon);
+
+        g_ascii_formatd(strlat, 32, "%.06f", lat);
+        g_ascii_formatd(strlon, 32, "%.06f", lon);
+        snprintf(buffer, sizeof(buffer), "%s, %s", strlat, strlon);
+
+        gtk_entry_set_text(GTK_ENTRY(oti.txt_origin), buffer);
+        gtk_toggle_button_set_active(
+                GTK_TOGGLE_BUTTON(oti.rad_use_text), TRUE);
+    }
+    /* Else use "End of Route" by default if they have a route. */
+    else if(_route.head != _route.tail)
+    {
+        /* There is no route, so make it the default. */
+        gtk_widget_set_sensitive(oti.rad_use_route, TRUE);
+        gtk_toggle_button_set_active(
+                GTK_TOGGLE_BUTTON(oti.rad_use_route), TRUE);
+        gtk_widget_grab_focus(oti.rad_use_route);
+    }
+    /* Else use "GPS Location" if they have GPS enabled. */
+    else
+    {
+        /* There is no route, so desensitize "Use End of Route." */
+        gtk_widget_set_sensitive(oti.rad_use_route, FALSE);
+        if(_enable_gps)
+        {
+            gtk_toggle_button_set_active(
+                    GTK_TOGGLE_BUTTON(oti.rad_use_gps), TRUE);
+            gtk_widget_grab_focus(oti.rad_use_gps);
+        }
+        /* Else use text. */
+        else
+        {
+            gtk_toggle_button_set_active(
+                    GTK_TOGGLE_BUTTON(oti.rad_use_text), TRUE);
+            gtk_widget_grab_focus(oti.txt_origin);
+        }
+    }
+
+    gtk_widget_show_all(dialog);
+
+    while(gtk_dialog_run(GTK_DIALOG(dialog)) ==GTK_RESPONSE_ACCEPT)
+    {
+        gchar origin_buffer[BUFFER_SIZE];
+        const gchar *source_url, *origin, *query;
+        gchar *file_uri_str = NULL;
+        gchar *bytes = NULL;
+        gint size;
+        GnomeVFSResult vfs_result;
+        GList *poi_list = NULL;
+
+        source_url = gtk_entry_get_text(GTK_ENTRY(txt_source_url));
+        if(!strlen(source_url))
+        {
+            popup_error(dialog, _("Please specify a source URL."));
+            continue;
+        }
+        else
+        {
+            g_free(_poi_dl_url);
+            _poi_dl_url = g_strdup(source_url);
+        }
+
+        if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(oti.rad_use_gps)))
+        {
+            gchar strlat[32];
+            gchar strlon[32];
+            latlon2unit(_gps.lat, _gps.lon, unitx, unity);
+            g_ascii_formatd(strlat, 32, "%.06f", _gps.lat);
+            g_ascii_formatd(strlon, 32, "%.06f", _gps.lon);
+            snprintf(origin_buffer, sizeof(origin_buffer),
+                    "%s, %s", strlat, strlon);
+            origin = origin_buffer;
+        }
+        else if(gtk_toggle_button_get_active(
+                    GTK_TOGGLE_BUTTON(oti.rad_use_route)))
+        {
+            gchar strlat[32];
+            gchar strlon[32];
+            Point *p;
+            gfloat lat, lon;
+
+            /* Use last non-zero route point. */
+            for(p = _route.tail; !p->unity; p--) { }
+
+            unitx = p->unitx;
+            unity = p->unity;
+            unit2latlon(p->unitx, p->unity, lat, lon);
+            g_ascii_formatd(strlat, 32, "%.06f", lat);
+            g_ascii_formatd(strlon, 32, "%.06f", lon);
+            snprintf(origin_buffer, sizeof(origin_buffer),
+                    "%s, %s", strlat, strlon);
+            origin = origin_buffer;
+        }
+        else
+        {
+            Point porig;
+            origin = gtk_entry_get_text(GTK_ENTRY(oti.txt_origin));
+            porig = locate_address(dialog, origin);
+            if(!porig.unity)
+                continue;
+        }
+
+        if(!strlen(origin))
+        {
+            popup_error(dialog, _("Please specify an origin."));
+            continue;
+        }
+
+        if(gtk_combo_box_get_active(GTK_COMBO_BOX(cmb_category)) == -1)
+        {
+            popup_error(dialog, _("Please specify a default category."));
+            continue;
+        }
+
+        query = gtk_entry_get_text(GTK_ENTRY(oti.txt_query));
+        if(!strlen(query))
+        {
+            popup_error(dialog, _("Please specify a query."));
+            continue;
+        }
+
+        /* Construct the URL. */
+        {
+            gchar *origin_escaped;
+            gchar *query_escaped;
+
+            origin_escaped = gnome_vfs_escape_string(origin);
+            query_escaped = gnome_vfs_escape_string(query);
+            file_uri_str = g_strdup_printf(
+                    source_url, origin_escaped, query_escaped,
+                    hildon_number_editor_get_value(
+                        HILDON_NUMBER_EDITOR(num_page)));
+            g_free(origin_escaped);
+            g_free(query_escaped);
+        }
+
+        /* Parse the given file as GPX. */
+        if(GNOME_VFS_OK != (vfs_result = gnome_vfs_read_entire_file(
+                        file_uri_str, &size, &bytes)))
+        {
+            popup_error(dialog, gnome_vfs_result_to_string(vfs_result));
+        }
+        else if(strncmp(bytes, "<?xml", strlen("<?xml")))
+        {
+            /* Not an XML document - must be bad locations. */
+            popup_error(dialog, _("Invalid origin or query."));
+            printf("bytes: %s\n", bytes);
+        }
+        else if(gpx_poi_parse(bytes, size, &poi_list))
+        {
+            /* Insert the POIs into the database. */
+            gint num_inserts = poi_list_insert(poi_list,
+                    GTK_COMBO_BOX(cmb_category));
+
+            if(num_inserts)
+            {
+                /* Hide the dialog. */
+                gtk_widget_hide(dialog);
+
+                /* Create a new dialog with the results. */
+                poi_list_dialog(unitx, unity, poi_list);
+            }
+
+            poi_list_free(poi_list);
+        }
+        else
+            popup_error(dialog, _("Error parsing GPX file."));
+
+        g_free(file_uri_str);
+        g_free(bytes);
+    }
+
+    /* Hide the dialog. */
+    gtk_widget_hide(dialog);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+gboolean
+poi_browse_dialog(gint unitx, gint unity)
+{
+    static GtkWidget *dialog = NULL;
+    static GtkWidget *table = NULL;
+    static GtkWidget *table2 = NULL;
+    static GtkWidget *label = NULL;
+    static GtkWidget *cmb_category = NULL;
+    static OriginToggleInfo oti;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(!dialog)
+    {
+        GtkEntryCompletion *origin_comp;
+
+        dialog = gtk_dialog_new_with_buttons(_("Browse POIs"),
+                GTK_WINDOW(_window), GTK_DIALOG_MODAL,
+                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+                NULL);
+
+        /* Enable the help button. */
+        ossohelp_dialog_help_enable(
+                GTK_DIALOG(dialog), HELP_ID_BROWSEPOI, _osso);
+
+        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+                table = gtk_table_new(3, 4, FALSE), TRUE, TRUE, 0);
+
+        /* Auto. */
+        gtk_table_attach(GTK_TABLE(table),
+                oti.rad_use_gps = gtk_radio_button_new_with_label(NULL,
+                    _("Use GPS Location")),
+                0, 1, 0, 1, GTK_FILL, 0, 2, 4);
+
+        /* Use End of Route. */
+        gtk_table_attach(GTK_TABLE(table),
+               oti.rad_use_route = gtk_radio_button_new_with_label_from_widget(
+                   GTK_RADIO_BUTTON(oti.rad_use_gps), _("Use End of Route")),
+               0, 1, 1, 2, GTK_FILL, 0, 2, 4);
+
+        gtk_table_attach(GTK_TABLE(table),
+                gtk_vseparator_new(),
+                1, 2, 0, 2, GTK_FILL, GTK_FILL, 2, 4);
+
+        /* Category. */
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Category")),
+                2, 3, 0, 1, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                cmb_category = poi_create_cat_combo(0),
+                3, 4, 0, 1, GTK_FILL, 0, 2, 4);
+        /* Add an extra, "<any>" category. */
+        {
+            GtkTreeIter iter;
+            GtkListStore *store = GTK_LIST_STORE(gtk_combo_box_get_model(
+                        GTK_COMBO_BOX(cmb_category)));
+            gtk_list_store_prepend(store, &iter);
+            gtk_list_store_set(store, &iter, 0, -1, 1, "<any>", -1);
+            gtk_combo_box_set_active_iter(GTK_COMBO_BOX(cmb_category), &iter);
+        }
+
+
+        /* Another table for the Origin and Query. */
+        gtk_table_attach(GTK_TABLE(table),
+                table2 = gtk_table_new(2, 2, FALSE),
+                0, 4, 2, 3, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+
+        /* Origin. */
+        gtk_table_attach(GTK_TABLE(table2),
+                oti.rad_use_text = gtk_radio_button_new_with_label_from_widget(
+                    GTK_RADIO_BUTTON(oti.rad_use_gps), _("Origin")),
+                0, 1, 0, 1, GTK_FILL, 0, 2, 4);
+        gtk_table_attach(GTK_TABLE(table2),
+                oti.txt_origin = gtk_entry_new(),
+                1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+        gtk_entry_set_width_chars(GTK_ENTRY(oti.txt_origin), 25);
+        g_object_set(G_OBJECT(oti.txt_origin), HILDON_AUTOCAP, FALSE, NULL);
+
+        /* Destination. */
+        gtk_table_attach(GTK_TABLE(table2),
+                label = gtk_label_new(_("Query")),
+                0, 1, 1, 2, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table2),
+                oti.txt_query = gtk_entry_new(),
+                1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+        gtk_entry_set_width_chars(GTK_ENTRY(oti.txt_query), 25);
+        g_object_set(G_OBJECT(oti.txt_query), HILDON_AUTOCAP, FALSE, NULL);
+
+        /* Set up auto-completion. */
+        origin_comp = gtk_entry_completion_new();
+        gtk_entry_completion_set_model(origin_comp,GTK_TREE_MODEL(_loc_model));
+        gtk_entry_completion_set_text_column(origin_comp, 0);
+        gtk_entry_set_completion(GTK_ENTRY(oti.txt_origin), origin_comp);
+
+        g_signal_connect(G_OBJECT(oti.rad_use_gps), "toggled",
+                          G_CALLBACK(origin_type_selected), &oti);
+        g_signal_connect(G_OBJECT(oti.rad_use_route), "toggled",
+                          G_CALLBACK(origin_type_selected), &oti);
+        g_signal_connect(G_OBJECT(oti.rad_use_text), "toggled",
+                          G_CALLBACK(origin_type_selected), &oti);
+    }
+
+    /* Initialize fields. */
+
+    if(unity != 0)
+    {
+        gchar buffer[80];
+        gchar strlat[32];
+        gchar strlon[32];
+        gfloat lat, lon;
+
+        unit2latlon(unitx, unity, lat, lon);
+
+        g_ascii_formatd(strlat, 32, "%.06f", lat);
+        g_ascii_formatd(strlon, 32, "%.06f", lon);
+        snprintf(buffer, sizeof(buffer), "%s, %s", strlat, strlon);
+
+        gtk_entry_set_text(GTK_ENTRY(oti.txt_origin), buffer);
+        gtk_toggle_button_set_active(
+                GTK_TOGGLE_BUTTON(oti.rad_use_text), TRUE);
+    }
+    /* Else use "End of Route" by default if they have a route. */
+    else if(_route.head != _route.tail)
+    {
+        /* There is no route, so make it the default. */
+        gtk_widget_set_sensitive(oti.rad_use_route, TRUE);
+        gtk_toggle_button_set_active(
+                GTK_TOGGLE_BUTTON(oti.rad_use_route), TRUE);
+        gtk_widget_grab_focus(oti.rad_use_route);
+    }
+    /* Else use "GPS Location" if they have GPS enabled. */
+    else
+    {
+        /* There is no route, so desensitize "Use End of Route." */
+        gtk_widget_set_sensitive(oti.rad_use_route, FALSE);
+        if(_enable_gps)
+        {
+            gtk_toggle_button_set_active(
+                    GTK_TOGGLE_BUTTON(oti.rad_use_gps), TRUE);
+            gtk_widget_grab_focus(oti.rad_use_gps);
+        }
+        /* Else use text. */
+        else
+        {
+            gtk_toggle_button_set_active(
+                    GTK_TOGGLE_BUTTON(oti.rad_use_text), TRUE);
+            gtk_widget_grab_focus(oti.txt_origin);
+        }
+    }
+
+    gtk_widget_show_all(dialog);
+
+    while(gtk_dialog_run(GTK_DIALOG(dialog)) ==GTK_RESPONSE_ACCEPT)
+    {
+        gchar buffer[BUFFER_SIZE];
+        const gchar *origin, *query;
+        gfloat lat, lon;
+        GList *poi_list = NULL;
+        gint cat_id;
+        gboolean is_cat = FALSE;
+        sqlite3_stmt *stmt;
+
+        if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(oti.rad_use_gps)))
+        {
+            gchar strlat[32];
+            gchar strlon[32];
+            latlon2unit(_gps.lat, _gps.lon, unitx, unity);
+            g_ascii_formatd(strlat, 32, "%.06f", _gps.lat);
+            g_ascii_formatd(strlon, 32, "%.06f", _gps.lon);
+            snprintf(buffer, sizeof(buffer), "%s, %s", strlat, strlon);
+            origin = buffer;
+        }
+        else if(gtk_toggle_button_get_active(
+                    GTK_TOGGLE_BUTTON(oti.rad_use_route)))
+        {
+            gchar strlat[32];
+            gchar strlon[32];
+            Point *p;
+            gfloat lat, lon;
+
+            /* Use last non-zero route point. */
+            for(p = _route.tail; !p->unity; p--) { }
+
+            unitx = p->unitx;
+            unity = p->unity;
+            unit2latlon(p->unitx, p->unity, lat, lon);
+            g_ascii_formatd(strlat, 32, "%.06f", lat);
+            g_ascii_formatd(strlon, 32, "%.06f", lon);
+            snprintf(buffer, sizeof(buffer), "%s, %s", strlat, strlon);
+            origin = buffer;
+        }
+        else
+        {
+            Point porig;
+            origin = gtk_entry_get_text(GTK_ENTRY(oti.txt_origin));
+            porig = locate_address(dialog, origin);
+            if(!porig.unity)
+                continue;
+        }
+
+        if(!strlen(origin))
+        {
+            popup_error(dialog, _("Please specify an origin."));
+            continue;
+        }
+
+        /* Check if we're doing a category search. */
+        {
+            GtkTreeIter iter;
+            if(gtk_combo_box_get_active_iter(
+                    GTK_COMBO_BOX(cmb_category), &iter))
+            {
+                gtk_tree_model_get(
+                        gtk_combo_box_get_model(GTK_COMBO_BOX(cmb_category)),
+                        &iter, 0, &cat_id, -1);
+                if(cat_id >= 0)
+                {
+                    is_cat = TRUE;
+                }
+            }
+        }
+
+        query = g_strdup_printf("%%%s%%",
+                gtk_entry_get_text(GTK_ENTRY(oti.txt_query)));
+
+        unit2latlon(unitx, unity, lat, lon);
+
+        if(is_cat)
+        {
+            printf("Searching for cat_id = %d\n", cat_id);
+            if(SQLITE_OK != sqlite3_bind_int(_stmt_browsecat_poi, 1, cat_id) ||
+               SQLITE_OK != sqlite3_bind_text(_stmt_browsecat_poi, 2, query,
+                   -1, g_free) ||
+               SQLITE_OK != sqlite3_bind_double(_stmt_browsecat_poi, 3, lat) ||
+               SQLITE_OK != sqlite3_bind_double(_stmt_browsecat_poi, 4, lon))
+            {
+                g_printerr("Failed to bind values for _stmt_browsecat_poi\n");
+                continue;
+            }
+            stmt = _stmt_browsecat_poi;
+        }
+        else
+        {
+            if(SQLITE_OK != sqlite3_bind_text(_stmt_browse_poi, 1, query,
+                        -1, g_free) ||
+               SQLITE_OK != sqlite3_bind_double(_stmt_browse_poi, 2, lat) ||
+               SQLITE_OK != sqlite3_bind_double(_stmt_browse_poi, 3, lon))
+            {
+                g_printerr("Failed to bind values for _stmt_browse_poi\n");
+                continue;
+            }
+            stmt = _stmt_browse_poi;
+        }
+
+        while(SQLITE_ROW == sqlite3_step(stmt))
+        {
+            PoiInfo *poi = g_slice_new(PoiInfo);
+            poi->poi_id = sqlite3_column_int(stmt, 0);
+            poi->cat_id = sqlite3_column_int(stmt, 1);
+            poi->lat = sqlite3_column_double(stmt, 2);
+            poi->lon = sqlite3_column_double(stmt, 3);
+            poi->label =g_strdup(sqlite3_column_text(stmt, 4));
+            poi->desc = g_strdup(sqlite3_column_text(stmt, 5));
+            poi->clabel=g_strdup(sqlite3_column_text(stmt, 6));
+            poi_list = g_list_prepend(poi_list, poi);
+        }
+        sqlite3_reset(stmt);
+
+        if(poi_list)
+        {
+            /* Hide the dialog. */
+            gtk_widget_hide(dialog);
+
+            /* Create a new dialog with the results. */
+            poi_list_dialog(unitx, unity, poi_list);
+            poi_list_free(poi_list);
+        }
+        else
+            popup_error(dialog, _("No POIs found."));
+    }
+
+    map_force_redraw();
+
+    /* Hide the dialog. */
+    gtk_widget_hide(dialog);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+/**
+ * Render all the POI data.  This should be done before rendering track data.
+ */
+void
+map_render_poi()
+{
+    gint unitx, unity;
+    gfloat lat1, lat2, lon1, lon2;
+    gchar buffer[100];
+    gint poix, poiy;
+    GdkPixbuf *pixbuf = NULL;
+    GError *error = NULL;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(_poi_db && _poi_zoom > _zoom)
+    {
+        buf2unit(0, _screen_height_pixels, unitx, unity);
+        unit2latlon(unitx, unity, lat1, lon1);
+        buf2unit(_screen_width_pixels, 0, unitx, unity);
+        unit2latlon(unitx, unity, lat2, lon2);
+
+        if(SQLITE_OK != sqlite3_bind_double(_stmt_select_poi, 1, lat1) ||
+           SQLITE_OK != sqlite3_bind_double(_stmt_select_poi, 2, lat2) ||
+           SQLITE_OK != sqlite3_bind_double(_stmt_select_poi, 3, lon1) ||
+           SQLITE_OK != sqlite3_bind_double(_stmt_select_poi, 4, lon2))
+        {
+            g_printerr("Failed to bind values for _stmt_select_poi\n");
+            return;
+        }
+
+        while(SQLITE_ROW == sqlite3_step(_stmt_select_poi))
+        {
+            lat1 = sqlite3_column_double(_stmt_select_poi, 0);
+            lon1 = sqlite3_column_double(_stmt_select_poi, 1);
+            gchar *poi_label = g_utf8_strdown(sqlite3_column_text(
+                    _stmt_select_poi, 3), -1);
+            gchar *cat_label = g_utf8_strdown(sqlite3_column_text(
+                    _stmt_select_poi, 6), -1);
+
+            latlon2unit(lat1, lon1, unitx, unity);
+            unit2buf(unitx, unity, poix, poiy);
+
+            /* Try to get icon for specific POI first. */
+            snprintf(buffer, sizeof(buffer), "%s/poi/%s.jpg",
+                    _poi_db_dirname, poi_label);
+            pixbuf = gdk_pixbuf_new_from_file(buffer, &error);
+            if(error)
+            {
+                /* No icon for specific POI - try for category. */
+                error = NULL;
+                snprintf(buffer, sizeof(buffer), "%s/poi/%s.jpg",
+                        _poi_db_dirname, cat_label);
+                pixbuf = gdk_pixbuf_new_from_file(buffer, &error);
+            }
+            if(error)
+            {
+                /* No icon for POI or for category.
+                 * Try default POI icon file. */
+                error = NULL;
+                snprintf(buffer, sizeof(buffer), "%s/poi/poi.jpg",
+                        _poi_db_dirname);
+                pixbuf = gdk_pixbuf_new_from_file(buffer, &error);
+            }
+            if(error)
+            {
+                /* No icon for POI or for category or default POI icon file.
+                   Draw default purple square. */
+                error = NULL;
+                gdk_draw_rectangle(_map_pixmap, _gc[COLORABLE_POI], TRUE,
+                        poix - (gint)(1.5f * _draw_width),
+                        poiy - (gint)(1.5f * _draw_width),
+                        3 * _draw_width,
+                        3 * _draw_width);
+            }
+            else
+            {
+                /* We found an icon to draw. */
+                gdk_draw_pixbuf(
+                        _map_pixmap,
+                        _gc[COLORABLE_POI],
+                        pixbuf,
+                        0, 0,
+                        poix - gdk_pixbuf_get_width(pixbuf) / 2,
+                        poiy - gdk_pixbuf_get_height(pixbuf) / 2,
+                        -1,-1,
+                        GDK_RGB_DITHER_NONE, 0, 0);
+                g_object_unref(pixbuf);
+            }
+
+            g_free(poi_label);
+            g_free(cat_label);
+        }
+        sqlite3_reset(_stmt_select_poi);
+    }
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+void
+poi_destroy()
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(_poi_db) 
+    { 
+        sqlite3_close(_poi_db); 
+        _poi_db = NULL; 
+    }
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
diff --git a/src/poi.h b/src/poi.h
new file mode 100644 (file)
index 0000000..bf1361c
--- /dev/null
+++ b/src/poi.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAEMO_MAPPER_POI_H
+#define MAEMO_MAPPER_POI_H
+
+typedef struct _PoiCategoryEditInfo PoiCategoryEditInfo;
+struct _PoiCategoryEditInfo
+{
+    GtkWidget *cmb_category;
+    gint cat_id;
+};
+
+void poi_db_connect();
+
+gboolean get_nearest_poi(gint unitx, gint unity, PoiInfo *poi);
+
+gboolean select_poi(gint unitx, gint unity, PoiInfo *poi, gboolean quick);
+
+gboolean category_list_dialog();
+
+gboolean poi_view_dialog(PoiInfo *poi, gint unitx, gint unity);
+gboolean poi_import_dialog(gint unitx, gint unity);
+gboolean poi_download_dialog(gint unitx, gint unity);
+gboolean poi_browse_dialog(gint unitx, gint unity);
+
+void map_render_poi();
+
+void poi_destroy();
+
+#endif /* ifndef MAEMO_MAPPER_POI_H */
diff --git a/src/settings.c b/src/settings.c
new file mode 100644 (file)
index 0000000..9fd38c1
--- /dev/null
@@ -0,0 +1,2149 @@
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#define _GNU_SOURCE
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <osso-helplib.h>
+#include <bt-dbus.h>
+#include <hildon-widgets/hildon-note.h>
+#include <hildon-widgets/hildon-color-button.h>
+#include <hildon-widgets/hildon-file-chooser-dialog.h>
+#include <hildon-widgets/hildon-number-editor.h>
+#include <hildon-widgets/hildon-banner.h>
+#include <gconf/gconf-client.h>
+
+#include "types.h"
+#include "data.h"
+#include "defines.h"
+
+#include "display.h"
+#include "gdk-pixbuf-rotate.h"
+#include "maps.h"
+#include "marshal.h"
+#include "poi.h"
+#include "settings.h"
+#include "util.h"
+
+/**
+ * Save all configuration data to GCONF.
+ */
+void
+settings_save()
+{
+    gchar *settings_dir;
+    GConfClient *gconf_client;
+    gchar buffer[16];
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    /* Initialize settings_dir. */
+    settings_dir = gnome_vfs_expand_initial_tilde(CONFIG_DIR_NAME);
+    g_mkdir_with_parents(settings_dir, 0700);
+
+    /* SAVE ALL GCONF SETTINGS. */
+
+    gconf_client = gconf_client_get_default();
+    if(!gconf_client)
+    {
+        popup_error(_window,
+                _("Failed to initialize GConf.  Settings were not saved."));
+        return;
+    }
+
+    /* Save GPS Receiver Type. */
+    gconf_client_set_string(gconf_client,
+            GCONF_KEY_GPS_RCVR_TYPE,
+            GPS_RCVR_ENUM_TEXT[_gri.type], NULL);
+
+    /* Save Bluetooth Receiver MAC. */
+    if(_gri.bt_mac)
+        gconf_client_set_string(gconf_client,
+                GCONF_KEY_GPS_BT_MAC, _gri.bt_mac, NULL);
+    else
+        gconf_client_unset(gconf_client,
+                GCONF_KEY_GPS_BT_MAC, NULL);
+
+    /* Save Bluetooth Receiver File. */
+    if(_gri.bt_file)
+        gconf_client_set_string(gconf_client,
+                GCONF_KEY_GPS_BT_FILE, _gri.bt_file, NULL);
+    else
+        gconf_client_unset(gconf_client,
+                GCONF_KEY_GPS_BT_FILE, NULL);
+
+    /* Save GPSD Host. */
+    if(_gri.gpsd_host)
+        gconf_client_set_string(gconf_client,
+                GCONF_KEY_GPS_GPSD_HOST, _gri.gpsd_host, NULL);
+    else
+        gconf_client_unset(gconf_client,
+                GCONF_KEY_GPS_GPSD_HOST, NULL);
+
+    /* Save GPSD Port. */
+    gconf_client_set_int(gconf_client,
+            GCONF_KEY_GPS_GPSD_PORT, _gri.gpsd_port, NULL);
+
+    /* Save File Path. */
+    if(_gri.file_path)
+        gconf_client_set_string(gconf_client,
+                GCONF_KEY_GPS_FILE_PATH, _gri.file_path, NULL);
+    else
+        gconf_client_unset(gconf_client,
+                GCONF_KEY_GPS_FILE_PATH, NULL);
+
+    /* Save Auto-Download. */
+    gconf_client_set_bool(gconf_client,
+            GCONF_KEY_AUTO_DOWNLOAD, _auto_download, NULL);
+
+    /* Save Auto-Download Pre-cache. */
+    gconf_client_set_int(gconf_client,
+            GCONF_KEY_AUTO_DOWNLOAD_PRECACHE, _auto_download_precache, NULL);
+
+    /* Save Auto-Center Sensitivity. */
+    gconf_client_set_int(gconf_client,
+            GCONF_KEY_CENTER_SENSITIVITY, _center_ratio, NULL);
+
+    /* Save Auto-Center Lead Amount. */
+    gconf_client_set_int(gconf_client,
+            GCONF_KEY_LEAD_AMOUNT, _lead_ratio, NULL);
+
+    /* Save Auto-Center Lead Fixed flag. */
+    gconf_client_set_bool(gconf_client,
+            GCONF_KEY_LEAD_IS_FIXED, _lead_is_fixed, NULL);
+
+    /* Save Auto-Rotate Sensitivity. */
+    gconf_client_set_int(gconf_client,
+            GCONF_KEY_ROTATE_SENSITIVITY, _rotate_sens, NULL);
+
+    /* Save Auto-Rotate Sensitivity. */
+    gconf_client_set_string(gconf_client,
+            GCONF_KEY_ROTATE_DIR, ROTATE_DIR_ENUM_TEXT[_rotate_dir], NULL);
+
+    /* Save Draw Line Width. */
+    gconf_client_set_int(gconf_client,
+            GCONF_KEY_DRAW_WIDTH, _draw_width, NULL);
+
+    /* Save Announce Advance Notice Ratio. */
+    gconf_client_set_int(gconf_client,
+            GCONF_KEY_ANNOUNCE_NOTICE, _announce_notice_ratio, NULL);
+
+    /* Save Enable Voice flag. */
+    gconf_client_set_bool(gconf_client,
+            GCONF_KEY_ENABLE_VOICE, _enable_voice, NULL);
+
+    /* Save fullscreen flag. */
+    gconf_client_set_bool(gconf_client,
+            GCONF_KEY_FULLSCREEN, _fullscreen, NULL);
+
+    /* Save Units. */
+    gconf_client_set_string(gconf_client,
+            GCONF_KEY_UNITS, UNITS_ENUM_TEXT[_units], NULL);
+
+    /* Save Custom Key Actions. */
+    {
+        gint i;
+        for(i = 0; i < CUSTOM_KEY_ENUM_COUNT; i++)
+            gconf_client_set_string(gconf_client,
+                    CUSTOM_KEY_GCONF[i],
+                    CUSTOM_ACTION_ENUM_TEXT[_action[i]], NULL);
+    }
+
+    /* Save Deg Format. */
+    gconf_client_set_string(gconf_client,
+            GCONF_KEY_DEG_FORMAT, DEG_FORMAT_ENUM_TEXT[_degformat], NULL);
+
+    /* Save Speed Limit On flag. */
+    gconf_client_set_bool(gconf_client,
+            GCONF_KEY_SPEED_LIMIT_ON, _speed_limit_on, NULL);
+
+    /* Save Speed Limit. */
+    gconf_client_set_int(gconf_client,
+            GCONF_KEY_SPEED_LIMIT, _speed_limit, NULL);
+
+    /* Save Speed Location. */
+    gconf_client_set_string(gconf_client,
+            GCONF_KEY_SPEED_LOCATION,
+            SPEED_LOCATION_ENUM_TEXT[_speed_location], NULL);
+
+    /* Save Info Font Size. */
+    gconf_client_set_string(gconf_client,
+            GCONF_KEY_INFO_FONT_SIZE,
+            INFO_FONT_ENUM_TEXT[_info_font_size], NULL);
+
+    /* Save Unblank Option. */
+    gconf_client_set_string(gconf_client,
+            GCONF_KEY_UNBLANK_SIZE,
+            UNBLANK_ENUM_TEXT[_unblank_option], NULL);
+
+    /* Save last saved latitude. */
+    gconf_client_set_float(gconf_client,
+            GCONF_KEY_LAST_LAT, _gps.lat, NULL);
+
+    /* Save last saved longitude. */
+    gconf_client_set_float(gconf_client,
+            GCONF_KEY_LAST_LON, _gps.lon, NULL);
+
+    /* Save last saved altitude. */
+    gconf_client_set_int(gconf_client,
+            GCONF_KEY_LAST_ALT, _pos.altitude, NULL);
+
+    /* Save last saved speed. */
+    gconf_client_set_float(gconf_client,
+            GCONF_KEY_LAST_SPEED, _gps.speed, NULL);
+
+    /* Save last saved heading. */
+    gconf_client_set_float(gconf_client,
+            GCONF_KEY_LAST_HEADING, _gps.heading, NULL);
+
+    /* Save last saved timestamp. */
+    gconf_client_set_float(gconf_client,
+            GCONF_KEY_LAST_TIME, _pos.time, NULL);
+
+    /* Save last center point. */
+    {
+        gfloat center_lat, center_lon;
+        unit2latlon(_center.unitx, _center.unity, center_lat, center_lon);
+
+        /* Save last center latitude. */
+        gconf_client_set_float(gconf_client,
+                GCONF_KEY_CENTER_LAT, center_lat, NULL);
+
+        /* Save last center longitude. */
+        gconf_client_set_float(gconf_client,
+                GCONF_KEY_CENTER_LON, center_lon, NULL);
+
+        /* Save last view angle. */
+        gconf_client_set_int(gconf_client,
+                GCONF_KEY_CENTER_ANGLE, _map_rotate_angle, NULL);
+    }
+
+    /* Save last Zoom Level. */
+    gconf_client_set_int(gconf_client,
+            GCONF_KEY_ZOOM, _zoom, NULL);
+
+    /* Save Route Directory. */
+    if(_route_dir_uri)
+        gconf_client_set_string(gconf_client,
+                GCONF_KEY_ROUTEDIR, _route_dir_uri, NULL);
+
+    /* Save the repositories. */
+    {
+        GList *curr = _repo_list;
+        GSList *temp_list = NULL;
+        gint curr_repo_index = 0;
+
+        for(curr = _repo_list; curr != NULL; curr = curr->next)
+        {
+            /* Build from each part of a repo, delimited by newline characters:
+             * 1. url
+             * 2. db_filename
+             * 3. dl_zoom_steps
+             * 4. view_zoom_steps
+             */
+            RepoData *rd = curr->data;
+            gchar buffer[BUFFER_SIZE];
+            snprintf(buffer, sizeof(buffer),
+                    "%s\t%s\t%s\t%d\t%d\t%d\t%d",
+                    rd->name,
+                    rd->url,
+                    rd->db_filename,
+                    rd->dl_zoom_steps,
+                    rd->view_zoom_steps,
+                    rd->double_size,
+                    rd->nextable);
+            temp_list = g_slist_append(temp_list, g_strdup(buffer));
+            if(rd == _curr_repo)
+                gconf_client_set_int(gconf_client,
+                        GCONF_KEY_CURRREPO, curr_repo_index, NULL);
+            curr_repo_index++;
+        }
+        gconf_client_set_list(gconf_client,
+                GCONF_KEY_REPOSITORIES, GCONF_VALUE_STRING, temp_list, NULL);
+    }
+
+    /* Save Last Track File. */
+    if(_track_file_uri)
+        gconf_client_set_string(gconf_client,
+                GCONF_KEY_TRACKFILE, _track_file_uri, NULL);
+
+    /* Save Auto-Center Mode. */
+    gconf_client_set_int(gconf_client,
+            GCONF_KEY_AUTOCENTER_MODE, _center_mode, NULL);
+
+    /* Save Auto-Center Rotate Flag. */
+    gconf_client_set_bool(gconf_client,
+            GCONF_KEY_AUTOCENTER_ROTATE, _center_rotate, NULL);
+
+    /* Save Show Zoom Level flag. */
+    gconf_client_set_bool(gconf_client,
+            GCONF_KEY_SHOWZOOMLEVEL, _show_zoomlevel, NULL);
+
+    /* Save Show Scale flag. */
+    gconf_client_set_bool(gconf_client,
+            GCONF_KEY_SHOWSCALE, _show_scale, NULL);
+
+    /* Save Show Compass Rose flag. */
+    gconf_client_set_bool(gconf_client,
+            GCONF_KEY_SHOWCOMPROSE, _show_comprose, NULL);
+
+    /* Save Show Tracks flag. */
+    gconf_client_set_bool(gconf_client,
+            GCONF_KEY_SHOWTRACKS, _show_paths & TRACKS_MASK, NULL);
+
+    /* Save Show Routes flag. */
+    gconf_client_set_bool(gconf_client,
+            GCONF_KEY_SHOWROUTES, _show_paths & ROUTES_MASK, NULL);
+
+    /* Save Show Velocity Vector flag. */
+    gconf_client_set_bool(gconf_client,
+            GCONF_KEY_SHOWVELVEC, _show_velvec, NULL);
+
+    /* Save Show POIs flag. */
+    gconf_client_set_bool(gconf_client,
+            GCONF_KEY_SHOWPOIS, _show_poi, NULL);
+
+    /* Save Enable GPS flag. */
+    gconf_client_set_bool(gconf_client,
+            GCONF_KEY_ENABLE_GPS, _enable_gps, NULL);
+
+    /* Save Route Locations. */
+    gconf_client_set_list(gconf_client,
+            GCONF_KEY_ROUTE_LOCATIONS, GCONF_VALUE_STRING, _loc_list, NULL);
+
+    /* Save GPS Info flag. */
+    gconf_client_set_bool(gconf_client,
+            GCONF_KEY_GPS_INFO, _gps_info, NULL);
+
+    /* Save Route Download URL Format. */
+    gconf_client_set_string(gconf_client,
+            GCONF_KEY_ROUTE_DL_URL, _route_dl_url, NULL);
+
+    /* Save Route Download Radius. */
+    gconf_client_set_int(gconf_client,
+            GCONF_KEY_ROUTE_DL_RADIUS, _route_dl_radius, NULL);
+
+    /* Save POI Download URL Format. */
+    gconf_client_set_string(gconf_client,
+            GCONF_KEY_POI_DL_URL, _poi_dl_url, NULL);
+
+    /* Save Colors. */
+    {
+        gint i;
+        for(i = 0; i < COLORABLE_ENUM_COUNT; i++)
+        {
+            snprintf(buffer, sizeof(buffer), "#%02x%02x%02x",
+                    _color[i].red >> 8,
+                    _color[i].green >> 8,
+                    _color[i].blue >> 8);
+            gconf_client_set_string(gconf_client,
+                    COLORABLE_GCONF[i], buffer, NULL);
+        }
+    }
+
+    /* Save POI database. */
+    if(_poi_db_filename)
+        gconf_client_set_string(gconf_client,
+                GCONF_KEY_POI_DB, _poi_db_filename, NULL);
+    else
+        gconf_client_unset(gconf_client, GCONF_KEY_POI_DB, NULL);
+
+    /* Save Show POI below zoom. */
+    gconf_client_set_int(gconf_client,
+            GCONF_KEY_POI_ZOOM, _poi_zoom, NULL);
+
+    gconf_client_clear_cache(gconf_client);
+    g_object_unref(gconf_client);
+    g_free(settings_dir);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+static void
+scan_cb_dev_found(DBusGProxy *sig_proxy, const gchar *bda,
+        const gchar *name, gpointer *class, guchar rssi, gint coff,
+        ScanInfo *scan_info)
+{
+    GtkTreeIter iter;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+    gtk_list_store_append(scan_info->store, &iter);
+    gtk_list_store_set(scan_info->store, &iter,
+            0, g_strdup(bda),
+            1, g_strdup(name),
+            -1);
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+static void
+scan_cb_search_complete(DBusGProxy *sig_proxy, ScanInfo *scan_info)
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+    gtk_widget_destroy(scan_info->banner);
+    dbus_g_proxy_disconnect_signal(sig_proxy, BTSEARCH_DEV_FOUND_SIG,
+            G_CALLBACK(scan_cb_dev_found), scan_info);
+    dbus_g_proxy_disconnect_signal(sig_proxy, BTSEARCH_SEARCH_COMPLETE_SIG,
+            G_CALLBACK(scan_cb_search_complete), scan_info);
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+static gint
+scan_start_search(ScanInfo *scan_info)
+{
+    GError *error = NULL;
+    DBusGConnection *dbus_conn;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    /* Initialize D-Bus. */
+    if(NULL == (dbus_conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error)))
+    {
+        g_printerr("Failed to open connection to D-Bus: %s.\n",
+                error->message);
+        return 1;
+    }
+
+    if(NULL == (scan_info->req_proxy = dbus_g_proxy_new_for_name(dbus_conn,
+            BTSEARCH_SERVICE,
+            BTSEARCH_REQ_PATH,
+            BTSEARCH_REQ_INTERFACE)))
+    {
+        g_printerr("Failed to create D-Bus request proxy for btsearch.");
+        return 2;
+    }
+
+    if(NULL == (scan_info->sig_proxy = dbus_g_proxy_new_for_name(dbus_conn,
+            BTSEARCH_SERVICE,
+            BTSEARCH_SIG_PATH,
+            BTSEARCH_SIG_INTERFACE)))
+    {
+        g_printerr("Failed to create D-Bus signal proxy for btsearch.");
+        return 2;
+    }
+
+    dbus_g_object_register_marshaller(
+            g_cclosure_user_marshal_VOID__STRING_STRING_POINTER_UCHAR_UINT,
+            G_TYPE_NONE,
+            G_TYPE_STRING,
+            G_TYPE_STRING,
+            DBUS_TYPE_G_UCHAR_ARRAY,
+            G_TYPE_UCHAR,
+            G_TYPE_UINT,
+            G_TYPE_INVALID);
+
+    dbus_g_proxy_add_signal(scan_info->sig_proxy,
+            BTSEARCH_DEV_FOUND_SIG,
+            G_TYPE_STRING,
+            G_TYPE_STRING,
+            DBUS_TYPE_G_UCHAR_ARRAY,
+            G_TYPE_UCHAR,
+            G_TYPE_UINT,
+            G_TYPE_INVALID);
+    dbus_g_proxy_connect_signal(scan_info->sig_proxy, BTSEARCH_DEV_FOUND_SIG,
+            G_CALLBACK(scan_cb_dev_found), scan_info, NULL);
+
+    dbus_g_proxy_add_signal(scan_info->sig_proxy,
+            BTSEARCH_SEARCH_COMPLETE_SIG,
+            G_TYPE_INVALID);
+    dbus_g_proxy_connect_signal(scan_info->sig_proxy,
+            BTSEARCH_SEARCH_COMPLETE_SIG,
+            G_CALLBACK(scan_cb_search_complete), scan_info, NULL);
+
+    error = NULL;
+    if(!dbus_g_proxy_call(scan_info->req_proxy, BTSEARCH_START_SEARCH_REQ,
+                &error, G_TYPE_INVALID, G_TYPE_INVALID))
+    {
+        if(error->domain == DBUS_GERROR
+                && error->code == DBUS_GERROR_REMOTE_EXCEPTION)
+        {
+            g_printerr("Caught remote method exception %s: %s",
+                    dbus_g_error_get_name(error),
+                    error->message);
+        }
+        else
+            g_printerr("Error: %s\n", error->message);
+        return 3;
+    }
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+    return 0;
+}
+
+/**
+ * Scan for all bluetooth devices.  This method can take a few seconds,
+ * during which the UI will freeze.
+ */
+static gboolean
+scan_bluetooth(GtkWidget *widget, ScanInfo *scan_info)
+{
+    GError *error = NULL;
+    GtkWidget *dialog = NULL;
+    GtkWidget *lst_devices = NULL;
+    GtkTreeViewColumn *column = NULL;
+    GtkCellRenderer *renderer = NULL;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    dialog = gtk_dialog_new_with_buttons(_("Select Bluetooth Device"),
+            GTK_WINDOW(scan_info->settings_dialog), GTK_DIALOG_MODAL,
+            GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+            GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+            NULL);
+
+    scan_info->scan_dialog = dialog;
+
+    scan_info->store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
+
+    gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 300);
+
+    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+            lst_devices = gtk_tree_view_new_with_model(
+                GTK_TREE_MODEL(scan_info->store)), TRUE, TRUE, 0);
+
+    g_object_unref(G_OBJECT(scan_info->store));
+
+    gtk_tree_selection_set_mode(
+            gtk_tree_view_get_selection(GTK_TREE_VIEW(lst_devices)),
+            GTK_SELECTION_SINGLE);
+    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(lst_devices), TRUE);
+
+    renderer = gtk_cell_renderer_text_new();
+    column = gtk_tree_view_column_new_with_attributes(
+            _("MAC"), renderer, "text", 0, NULL);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(lst_devices), column);
+
+    renderer = gtk_cell_renderer_text_new();
+    column = gtk_tree_view_column_new_with_attributes(
+            _("Description"), renderer, "text", 1, NULL);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(lst_devices), column);
+
+    gtk_widget_show_all(dialog);
+
+    scan_info->banner = hildon_banner_show_animation(dialog, NULL,
+            _("Scanning for Bluetooth Devices"));
+
+    if(scan_start_search(scan_info))
+    {
+        gtk_widget_destroy(scan_info->banner);
+        popup_error(scan_info->settings_dialog,
+                _("An error occurred while attempting to scan for "
+                "bluetooth devices."));
+    }
+    else while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
+    {
+        GtkTreeIter iter;
+        if(gtk_tree_selection_get_selected(
+                    gtk_tree_view_get_selection(GTK_TREE_VIEW(lst_devices)),
+                    NULL, &iter))
+        {
+            gchar *mac;
+            gtk_tree_model_get(GTK_TREE_MODEL(scan_info->store),
+                    &iter, 0, &mac, -1);
+            gtk_entry_set_text(GTK_ENTRY(scan_info->txt_gps_bt_mac), mac);
+            break;
+        }
+        else
+            popup_error(dialog,
+                    _("Please select a bluetooth device from the list."));
+    }
+
+    gtk_widget_destroy(dialog);
+
+    /* Clean up D-Bus. */
+    dbus_g_proxy_call(scan_info->req_proxy, BTSEARCH_STOP_SEARCH_REQ,
+                &error, G_TYPE_INVALID, G_TYPE_INVALID);
+    g_object_unref(scan_info->req_proxy);
+    g_object_unref(scan_info->sig_proxy);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+settings_dialog_browse_forfile(GtkWidget *widget, BrowseInfo *browse_info)
+{
+    GtkWidget *dialog;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    dialog = GTK_WIDGET(
+            hildon_file_chooser_dialog_new(GTK_WINDOW(browse_info->dialog),
+            GTK_FILE_CHOOSER_ACTION_OPEN));
+
+    gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(dialog), TRUE);
+    gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),
+            gtk_entry_get_text(GTK_ENTRY(browse_info->txt)));
+
+    if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(dialog)))
+    {
+        gchar *filename = gtk_file_chooser_get_filename(
+                GTK_FILE_CHOOSER(dialog));
+        gtk_entry_set_text(GTK_ENTRY(browse_info->txt), filename);
+        g_free(filename);
+    }
+
+    gtk_widget_destroy(dialog);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+settings_dialog_hardkeys_reset(GtkWidget *widget, KeysDialogInfo *cdi)
+{
+    GtkWidget *confirm;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    confirm = hildon_note_new_confirmation(GTK_WINDOW(_window),
+            _("Reset all hardware keys to their original defaults?"));
+
+    if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm)))
+    {
+        gint i;
+        for(i = 0; i < CUSTOM_KEY_ENUM_COUNT; i++)
+            gtk_combo_box_set_active(GTK_COMBO_BOX(cdi->cmb[i]),
+                    CUSTOM_KEY_DEFAULT[i]);
+    }
+    gtk_widget_destroy(confirm);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+settings_dialog_hardkeys(GtkWidget *widget, GtkWidget *parent)
+{
+    gint i;
+    static GtkWidget *dialog = NULL;
+    static GtkWidget *table = NULL;
+    static GtkWidget *label = NULL;
+    static KeysDialogInfo bdi;
+    static GtkWidget *btn_defaults = NULL;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(dialog == NULL)
+    {
+        dialog = gtk_dialog_new_with_buttons(_("Hardware Keys"),
+                GTK_WINDOW(parent), GTK_DIALOG_MODAL,
+                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+                NULL);
+
+        gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
+                btn_defaults = gtk_button_new_with_label(_("Reset...")));
+        g_signal_connect(G_OBJECT(btn_defaults), "clicked",
+                          G_CALLBACK(settings_dialog_hardkeys_reset), &bdi);
+
+        gtk_dialog_add_button(GTK_DIALOG(dialog),
+                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
+
+        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+                table = gtk_table_new(2, 9, FALSE), TRUE, TRUE, 0);
+        for(i = 0; i < CUSTOM_KEY_ENUM_COUNT; i++)
+        {
+            gint j;
+            gtk_table_attach(GTK_TABLE(table),
+                    label = gtk_label_new(""),
+                    0, 1, i, i + 1, GTK_FILL, 0, 2, 1);
+            gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+            gtk_label_set_markup(GTK_LABEL(label), CUSTOM_KEY_ICON[i]);
+            gtk_table_attach(GTK_TABLE(table),
+                    bdi.cmb[i] = gtk_combo_box_new_text(),
+                    1, 2, i, i + 1, GTK_FILL, 0, 2, 1);
+            for(j = 0; j < CUSTOM_ACTION_ENUM_COUNT; j++)
+                gtk_combo_box_append_text(GTK_COMBO_BOX(bdi.cmb[i]),
+                        CUSTOM_ACTION_ENUM_TEXT[j]);
+        }
+    }
+
+    /* Initialize contents of the combo boxes. */
+    for(i = 0; i < CUSTOM_KEY_ENUM_COUNT; i++)
+        gtk_combo_box_set_active(GTK_COMBO_BOX(bdi.cmb[i]), _action[i]);
+
+    gtk_widget_show_all(dialog);
+
+OUTER_WHILE:
+    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
+    {
+        /* Check for duplicates. */
+        for(i = 0; i < CUSTOM_KEY_ENUM_COUNT; i++)
+        {
+            gint j;
+            for(j = i + 1; j < CUSTOM_KEY_ENUM_COUNT; j++)
+            {
+                if(gtk_combo_box_get_active(GTK_COMBO_BOX(bdi.cmb[i]))
+                        == gtk_combo_box_get_active(GTK_COMBO_BOX(bdi.cmb[j])))
+                {
+                    GtkWidget *confirm;
+                    gchar *buffer = g_strdup_printf("%s:\n    %s\n%s",
+                        _("The following action is mapped to multiple keys"),
+                        CUSTOM_ACTION_ENUM_TEXT[gtk_combo_box_get_active(
+                            GTK_COMBO_BOX(bdi.cmb[i]))],
+                        _("Continue?"));
+                    confirm = hildon_note_new_confirmation(GTK_WINDOW(_window),
+                            buffer);
+
+                    if(GTK_RESPONSE_OK != gtk_dialog_run(GTK_DIALOG(confirm)))
+                    {
+                        gtk_widget_destroy(confirm);
+                        goto OUTER_WHILE;
+                    }
+                    gtk_widget_destroy(confirm);
+                }
+            }
+        }
+        for(i = 0; i < CUSTOM_KEY_ENUM_COUNT; i++)
+            _action[i] = gtk_combo_box_get_active(GTK_COMBO_BOX(bdi.cmb[i]));
+        break;
+    }
+
+    gtk_widget_hide(dialog);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+settings_dialog_colors_reset(GtkWidget *widget, ColorsDialogInfo *cdi)
+{
+    GtkWidget *confirm;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    confirm = hildon_note_new_confirmation(GTK_WINDOW(_window),
+            _("Reset all colors to their original defaults?"));
+
+    if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm)))
+    {
+        gint i;
+        for(i = 0; i < COLORABLE_ENUM_COUNT; i++)
+        {
+            hildon_color_button_set_color(
+                    HILDON_COLOR_BUTTON(cdi->col[i]),
+                    &COLORABLE_DEFAULT[i]);
+        }
+    }
+    gtk_widget_destroy(confirm);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+static gboolean
+settings_dialog_colors(GtkWidget *widget, GtkWidget *parent)
+{
+    static GtkWidget *dialog = NULL;
+    static GtkWidget *table = NULL;
+    static GtkWidget *label = NULL;
+    static GtkWidget *btn_defaults = NULL;
+    static ColorsDialogInfo cdi;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(dialog == NULL)
+    {
+        dialog = gtk_dialog_new_with_buttons(_("Colors"),
+                GTK_WINDOW(parent), GTK_DIALOG_MODAL,
+                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+                NULL);
+
+        gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
+                btn_defaults = gtk_button_new_with_label(_("Reset...")));
+        g_signal_connect(G_OBJECT(btn_defaults), "clicked",
+                          G_CALLBACK(settings_dialog_colors_reset), &cdi);
+
+        gtk_dialog_add_button(GTK_DIALOG(dialog),
+                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
+
+        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+                table = gtk_table_new(4, 3, FALSE), TRUE, TRUE, 0);
+
+        /* GPS. */
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("GPS")),
+                0, 1, 0, 1, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                cdi.col[COLORABLE_MARK] = hildon_color_button_new(),
+                1, 2, 0, 1, 0, 0, 2, 4);
+        gtk_table_attach(GTK_TABLE(table),
+                cdi.col[COLORABLE_MARK_VELOCITY] = hildon_color_button_new(),
+                2, 3, 0, 1, 0, 0, 2, 4);
+        gtk_table_attach(GTK_TABLE(table),
+                cdi.col[COLORABLE_MARK_OLD] = hildon_color_button_new(),
+                3, 4, 0, 1, 0, 0, 2, 4);
+
+        /* Track. */
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Track")),
+                0, 1, 1, 2, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                cdi.col[COLORABLE_TRACK] = hildon_color_button_new(),
+                1, 2, 1, 2, 0, 0, 2, 4);
+        gtk_table_attach(GTK_TABLE(table),
+                cdi.col[COLORABLE_TRACK_MARK] = hildon_color_button_new(),
+                2, 3, 1, 2, 0, 0, 2, 4);
+        gtk_table_attach(GTK_TABLE(table),
+                cdi.col[COLORABLE_TRACK_BREAK] = hildon_color_button_new(),
+                3, 4, 1, 2, 0, 0, 2, 4);
+
+        /* Route. */
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Route")),
+                0, 1, 2, 3, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                cdi.col[COLORABLE_ROUTE] = hildon_color_button_new(),
+                1, 2, 2, 3, 0, 0, 2, 4);
+        gtk_table_attach(GTK_TABLE(table),
+                cdi.col[COLORABLE_ROUTE_WAY] = hildon_color_button_new(),
+                2, 3, 2, 3, 0, 0, 2, 4);
+        gtk_table_attach(GTK_TABLE(table),
+                cdi.col[COLORABLE_ROUTE_BREAK] = hildon_color_button_new(),
+                3, 4, 2, 3, 0, 0, 2, 4);
+
+        /* POI. */
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("POI")),
+                0, 1, 3, 4, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                cdi.col[COLORABLE_POI] = hildon_color_button_new(),
+                1, 2, 3, 4, 0, 0, 2, 4);
+    }
+
+    /* Initialize GPS. */
+    hildon_color_button_set_color(
+            HILDON_COLOR_BUTTON(cdi.col[COLORABLE_MARK]),
+            &_color[COLORABLE_MARK]);
+    hildon_color_button_set_color(
+            HILDON_COLOR_BUTTON(cdi.col[COLORABLE_MARK_VELOCITY]),
+            &_color[COLORABLE_MARK_VELOCITY]);
+    hildon_color_button_set_color(
+            HILDON_COLOR_BUTTON(cdi.col[COLORABLE_MARK_OLD]),
+            &_color[COLORABLE_MARK_OLD]);
+
+    /* Initialize Track. */
+    hildon_color_button_set_color(
+            HILDON_COLOR_BUTTON(cdi.col[COLORABLE_TRACK]),
+            &_color[COLORABLE_TRACK]);
+    hildon_color_button_set_color(
+            HILDON_COLOR_BUTTON(cdi.col[COLORABLE_TRACK_MARK]),
+            &_color[COLORABLE_TRACK_MARK]);
+    hildon_color_button_set_color(
+            HILDON_COLOR_BUTTON(cdi.col[COLORABLE_TRACK_BREAK]),
+            &_color[COLORABLE_TRACK_BREAK]);
+
+    /* Initialize Route. */
+    hildon_color_button_set_color(
+            HILDON_COLOR_BUTTON(cdi.col[COLORABLE_ROUTE]),
+            &_color[COLORABLE_ROUTE]);
+    hildon_color_button_set_color(
+            HILDON_COLOR_BUTTON(cdi.col[COLORABLE_ROUTE_WAY]),
+            &_color[COLORABLE_ROUTE_WAY]);
+    hildon_color_button_set_color(
+            HILDON_COLOR_BUTTON(cdi.col[COLORABLE_ROUTE_BREAK]),
+            &_color[COLORABLE_ROUTE_BREAK]);
+
+    /* Initialize POI. */
+    hildon_color_button_set_color(
+            HILDON_COLOR_BUTTON(cdi.col[COLORABLE_POI]),
+            &_color[COLORABLE_POI]);
+
+    gtk_widget_show_all(dialog);
+
+    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
+    {
+        GdkColor *color;
+
+        color = hildon_color_button_get_color(
+                HILDON_COLOR_BUTTON(cdi.col[COLORABLE_MARK]));
+        _color[COLORABLE_MARK] = *color;
+
+        color = hildon_color_button_get_color(
+                HILDON_COLOR_BUTTON(cdi.col[COLORABLE_MARK_VELOCITY]));
+        _color[COLORABLE_MARK_VELOCITY] = *color;
+
+        color = hildon_color_button_get_color(
+                HILDON_COLOR_BUTTON(cdi.col[COLORABLE_MARK_OLD]));
+        _color[COLORABLE_MARK_OLD] = *color;
+
+        color = hildon_color_button_get_color(
+                HILDON_COLOR_BUTTON(cdi.col[COLORABLE_TRACK]));
+        _color[COLORABLE_TRACK] = *color;
+
+        color = hildon_color_button_get_color(
+                HILDON_COLOR_BUTTON(cdi.col[COLORABLE_TRACK_MARK]));
+        _color[COLORABLE_TRACK_MARK] = *color;
+
+        color = hildon_color_button_get_color(
+                HILDON_COLOR_BUTTON(cdi.col[COLORABLE_TRACK_BREAK]));
+        _color[COLORABLE_TRACK_BREAK] = *color;
+
+        color = hildon_color_button_get_color(
+                HILDON_COLOR_BUTTON(cdi.col[COLORABLE_ROUTE]));
+        _color[COLORABLE_ROUTE] = *color;
+
+        color = hildon_color_button_get_color(
+                HILDON_COLOR_BUTTON(cdi.col[COLORABLE_ROUTE_WAY]));
+        _color[COLORABLE_ROUTE_WAY] = *color;
+
+        color = hildon_color_button_get_color(
+                HILDON_COLOR_BUTTON(cdi.col[COLORABLE_ROUTE_BREAK]));
+        _color[COLORABLE_ROUTE_BREAK] = *color;
+
+        color = hildon_color_button_get_color(
+                HILDON_COLOR_BUTTON(cdi.col[COLORABLE_POI]));
+        _color[COLORABLE_POI] = *color;
+
+        update_gcs();
+        break;
+    }
+
+    map_force_redraw();
+
+    gtk_widget_hide(dialog);
+
+    vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+    return TRUE;
+}
+
+/**
+ * Bring up the Settings dialog.  Return TRUE if and only if the recever
+ * information has changed (MAC or channel).
+ */
+gboolean
+settings_dialog()
+{
+    static GtkWidget *dialog = NULL;
+    static GtkWidget *notebook = NULL;
+    static GtkWidget *table = NULL;
+    static GtkWidget *hbox = NULL;
+    static GtkWidget *label = NULL;
+    static GtkWidget *rad_gps_bt = NULL;
+    static GtkWidget *rad_gps_gpsd = NULL;
+    static GtkWidget *rad_gps_file = NULL;
+    static GtkWidget *txt_gps_bt_mac = NULL;
+    static GtkWidget *txt_gps_gpsd_host = NULL;
+    static GtkWidget *num_gps_gpsd_port = NULL;
+    static GtkWidget *txt_gps_file_path = NULL;
+    static GtkWidget *num_center_ratio = NULL;
+    static GtkWidget *num_lead_ratio = NULL;
+    static GtkWidget *chk_lead_is_fixed = NULL;
+    static GtkWidget *num_rotate_sens = NULL;
+    static GtkWidget *cmb_rotate_dir = NULL;
+    static GtkWidget *num_announce_notice = NULL;
+    static GtkWidget *chk_enable_voice = NULL;
+    static GtkWidget *num_draw_width = NULL;
+    static GtkWidget *cmb_units = NULL;
+    static GtkWidget *cmb_degformat = NULL;
+    static GtkWidget *btn_scan = NULL;
+    static GtkWidget *btn_browse_gps = NULL;
+    static GtkWidget *btn_buttons = NULL;
+    static GtkWidget *btn_colors = NULL;
+
+    static GtkWidget *txt_poi_db = NULL;
+    static GtkWidget *btn_browse_poi = NULL;
+    static GtkWidget *num_poi_zoom = NULL;
+    static GtkWidget *num_auto_download_precache = NULL;
+    static GtkWidget *chk_speed_limit_on = NULL;
+    static GtkWidget *num_speed = NULL;
+    static GtkWidget *cmb_speed_location = NULL;
+    static GtkWidget *cmb_unblank_option = NULL;
+    static GtkWidget *cmb_info_font_size = NULL;
+
+    static BrowseInfo poi_browse_info = {0, 0};
+    static BrowseInfo gps_file_browse_info = {0, 0};
+    static ScanInfo scan_info = {0};
+    gboolean rcvr_changed = FALSE;
+    gint i;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(dialog == NULL)
+    {
+        dialog = gtk_dialog_new_with_buttons(_("Settings"),
+                GTK_WINDOW(_window), GTK_DIALOG_MODAL,
+                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+                NULL);
+
+        /* Enable the help button. */
+        ossohelp_dialog_help_enable(
+                GTK_DIALOG(dialog), HELP_ID_SETTINGS, _osso);
+
+        gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
+               btn_buttons = gtk_button_new_with_label(_("Hardware Keys...")));
+
+        gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
+                btn_colors = gtk_button_new_with_label(_("Colors...")));
+
+        gtk_dialog_add_button(GTK_DIALOG(dialog),
+                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
+
+        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+                notebook = gtk_notebook_new(), TRUE, TRUE, 0);
+
+        /* Receiver page. */
+        gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
+                table = gtk_table_new(3, 4, FALSE),
+                label = gtk_label_new(_("GPS")));
+
+        /* Receiver MAC Address. */
+        gtk_table_attach(GTK_TABLE(table),
+                rad_gps_bt = gtk_radio_button_new_with_label(
+                    NULL, _("MAC Address")),
+                0, 1, 0, 1, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                hbox = gtk_hbox_new(FALSE, 4),
+                1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+        gtk_box_pack_start(GTK_BOX(hbox),
+                txt_gps_bt_mac = gtk_entry_new(),
+                TRUE, TRUE, 0);
+        gtk_box_pack_start(GTK_BOX(hbox),
+                btn_scan = gtk_button_new_with_label(_("Scan...")),
+                FALSE, FALSE, 0);
+
+        /* GPSD Hostname and Port. */
+        gtk_table_attach(GTK_TABLE(table),
+                rad_gps_gpsd = gtk_radio_button_new_with_label_from_widget(
+                    GTK_RADIO_BUTTON(rad_gps_bt), _("GPSD Host")),
+                0, 1, 1, 2, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                hbox = gtk_hbox_new(FALSE, 4),
+                1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+        gtk_box_pack_start(GTK_BOX(hbox),
+                txt_gps_gpsd_host = gtk_entry_new(),
+                TRUE, TRUE, 0);
+        gtk_box_pack_start(GTK_BOX(hbox),
+                label = gtk_label_new(_("Port")),
+                FALSE, FALSE, 0);
+        gtk_box_pack_start(GTK_BOX(hbox),
+                num_gps_gpsd_port = hildon_number_editor_new(1, 65535),
+                FALSE, FALSE, 0);
+
+        /* File Path (RFComm). */
+        gtk_table_attach(GTK_TABLE(table),
+                rad_gps_file = gtk_radio_button_new_with_label_from_widget(
+                    GTK_RADIO_BUTTON(rad_gps_bt), _("File Path")),
+                0, 1, 2, 3, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                hbox = gtk_hbox_new(FALSE, 4),
+                1, 2, 2, 3, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+        gtk_box_pack_start(GTK_BOX(hbox),
+                txt_gps_file_path = gtk_entry_new(),
+                TRUE, TRUE, 0);
+        gtk_box_pack_start(GTK_BOX(hbox),
+                btn_browse_gps = gtk_button_new_with_label(_("Browse...")),
+                FALSE, FALSE, 0);
+
+
+        /* Auto-Center page. */
+        gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
+                table = gtk_table_new(3, 3, FALSE),
+                label = gtk_label_new(_("Auto-Center")));
+
+        /* Auto-Center Pan Sensitivity. */
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Pan Sensitivity")),
+                0, 1, 0, 1, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
+                1, 2, 0, 1, GTK_FILL, 0, 2, 4);
+        gtk_container_add(GTK_CONTAINER(label),
+                num_center_ratio = hildon_controlbar_new());
+        hildon_controlbar_set_range(HILDON_CONTROLBAR(num_center_ratio), 1,10);
+        force_min_visible_bars(HILDON_CONTROLBAR(num_center_ratio), 1);
+
+        /* Lead Amount. */
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Lead Amount")),
+                0, 1, 1, 2, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
+                1, 2, 1, 2, GTK_FILL, 0, 2, 4);
+        gtk_container_add(GTK_CONTAINER(label),
+                num_lead_ratio = hildon_controlbar_new());
+        hildon_controlbar_set_range(HILDON_CONTROLBAR(num_lead_ratio), 1, 10);
+        force_min_visible_bars(HILDON_CONTROLBAR(num_lead_ratio), 1);
+
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
+                2, 3, 1, 2, GTK_FILL, 0, 2, 4);
+        gtk_container_add(GTK_CONTAINER(label),
+            chk_lead_is_fixed = gtk_check_button_new_with_label(_("Fixed")));
+
+        /* Auto-Center Rotate Sensitivity. */
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Rotate Sensit.")),
+                0, 1, 2, 3, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                num_rotate_sens = hildon_controlbar_new(),
+                1, 2, 2, 3, GTK_FILL, 0, 2, 4);
+        hildon_controlbar_set_range(HILDON_CONTROLBAR(num_rotate_sens), 1,10);
+        force_min_visible_bars(HILDON_CONTROLBAR(num_rotate_sens), 1);
+
+        gtk_table_attach(GTK_TABLE(table),
+                hbox = gtk_hbox_new(FALSE, 4),
+                2, 3, 2, 3, GTK_FILL, 0, 2, 4);
+        gtk_box_pack_start(GTK_BOX(hbox),
+                label = gtk_label_new(_("Points")),
+                TRUE, TRUE, 4);
+        gtk_box_pack_start(GTK_BOX(hbox),
+                cmb_rotate_dir = gtk_combo_box_new_text(),
+                TRUE, TRUE, 4);
+        for(i = 0; i < ROTATE_DIR_ENUM_COUNT; i++)
+            gtk_combo_box_append_text(GTK_COMBO_BOX(cmb_rotate_dir),
+                    ROTATE_DIR_ENUM_TEXT[i]);
+
+        /* Announcement. */
+        gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
+                table = gtk_table_new(2, 3, FALSE),
+                label = gtk_label_new(_("Announce")));
+
+        /* Announcement Advance Notice. */
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Advance Notice")),
+                0, 1, 0, 1, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                num_announce_notice = hildon_controlbar_new(),
+                1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+        hildon_controlbar_set_range(
+                HILDON_CONTROLBAR(num_announce_notice), 1, 20);
+        force_min_visible_bars(HILDON_CONTROLBAR(num_announce_notice), 1);
+
+        /* Enable Voice. */
+        gtk_table_attach(GTK_TABLE(table),
+                chk_enable_voice = gtk_check_button_new_with_label(
+                    _("Enable Voice Synthesis (requires flite)")),
+                0, 2, 1, 2, GTK_FILL, 0, 2, 4);
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chk_enable_voice),
+                _enable_voice);
+
+        /* Misc. page. */
+        gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
+                table = gtk_table_new(3, 5, FALSE),
+                label = gtk_label_new(_("Misc.")));
+
+        /* Line Width. */
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Line Width")),
+                0, 1, 0, 1, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                num_draw_width = hildon_controlbar_new(),
+                1, 5, 0, 1, GTK_FILL, 0, 2, 4);
+        hildon_controlbar_set_range(HILDON_CONTROLBAR(num_draw_width), 1, 20);
+        force_min_visible_bars(HILDON_CONTROLBAR(num_draw_width), 1);
+
+        /* Unblank Screen */
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Unblank Screen")),
+                0, 1, 1, 2, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                cmb_unblank_option = gtk_combo_box_new_text(),
+                1, 5, 1, 2, GTK_FILL, 0, 2, 4);
+        for(i = 0; i < UNBLANK_ENUM_COUNT; i++)
+            gtk_combo_box_append_text(GTK_COMBO_BOX(cmb_unblank_option),
+                    UNBLANK_ENUM_TEXT[i]);
+
+        /* Information Font Size. */
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Info Font Size")),
+                0, 1, 2, 3, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                cmb_info_font_size = gtk_combo_box_new_text(),
+                1, 2, 2, 3, GTK_FILL, 0, 2, 4);
+        for(i = 0; i < INFO_FONT_ENUM_COUNT; i++)
+            gtk_combo_box_append_text(GTK_COMBO_BOX(cmb_info_font_size),
+                    INFO_FONT_ENUM_TEXT[i]);
+
+        gtk_table_attach(GTK_TABLE(table),
+                gtk_vseparator_new(),
+                2, 3, 2, 3, GTK_EXPAND | GTK_FILL, GTK_FILL, 2,4);
+
+
+        /* Units. */
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Units")),
+                3, 4, 2, 3, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                cmb_units = gtk_combo_box_new_text(),
+                4, 5, 2, 3, GTK_FILL, 0, 2, 4);
+        for(i = 0; i < UNITS_ENUM_COUNT; i++)
+            gtk_combo_box_append_text(
+                    GTK_COMBO_BOX(cmb_units), UNITS_ENUM_TEXT[i]);
+
+        /* Misc. 2 page. */
+        gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
+                table = gtk_table_new(3, 4, FALSE),
+                label = gtk_label_new(_("Misc. 2")));
+
+        /* Degrees format */
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Degrees Format")),
+                0, 1, 0, 1, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
+                1, 2, 0, 1, GTK_FILL, 0, 2, 4);
+        gtk_container_add(GTK_CONTAINER(label),
+                cmb_degformat = gtk_combo_box_new_text());
+        for(i = 0; i < DEG_FORMAT_ENUM_COUNT; i++)
+            gtk_combo_box_append_text(GTK_COMBO_BOX(cmb_degformat),
+                DEG_FORMAT_ENUM_TEXT[i]);
+
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Auto-Download Pre-cache")),
+                0, 1, 1, 2, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                num_auto_download_precache = hildon_controlbar_new(),
+                1, 2, 1, 2, GTK_FILL, 0, 2, 4);
+        hildon_controlbar_set_range(
+                HILDON_CONTROLBAR(num_auto_download_precache), 1, 5);
+        force_min_visible_bars(
+                HILDON_CONTROLBAR(num_auto_download_precache), 1);
+
+        /* Speed warner. */
+        gtk_table_attach(GTK_TABLE(table),
+                hbox = gtk_hbox_new(FALSE, 4),
+                0, 4, 2, 3, GTK_FILL, 0, 2, 4);
+
+        gtk_box_pack_start(GTK_BOX(hbox),
+                chk_speed_limit_on = gtk_check_button_new_with_label(
+                    _("Speed Limit")),
+                FALSE, FALSE, 0);
+
+        gtk_box_pack_start(GTK_BOX(hbox),
+                label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
+                FALSE, FALSE, 0);
+        gtk_container_add(GTK_CONTAINER(label),
+                num_speed = hildon_number_editor_new(0, 999));
+
+        gtk_box_pack_start(GTK_BOX(hbox),
+                label = gtk_label_new(_("Location")),
+                FALSE, FALSE, 0);
+        gtk_box_pack_start(GTK_BOX(hbox),
+                label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
+                FALSE, FALSE, 0);
+        gtk_container_add(GTK_CONTAINER(label),
+                cmb_speed_location = gtk_combo_box_new_text());
+        for(i = 0; i < SPEED_LOCATION_ENUM_COUNT; i++)
+            gtk_combo_box_append_text(GTK_COMBO_BOX(cmb_speed_location),
+                    SPEED_LOCATION_ENUM_TEXT[i]);
+
+
+        /* POI page */
+        gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
+                table = gtk_table_new(2, 3, FALSE),
+                label = gtk_label_new(_("POI")));
+
+        /* POI database. */
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("POI database")),
+                0, 1, 1, 2, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                hbox = gtk_hbox_new(FALSE, 4),
+                1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+        gtk_box_pack_start(GTK_BOX(hbox),
+                txt_poi_db = gtk_entry_new(),
+                TRUE, TRUE, 0);
+        gtk_box_pack_start(GTK_BOX(hbox),
+                btn_browse_poi = gtk_button_new_with_label(_("Browse...")),
+                FALSE, FALSE, 0);
+
+        /* Show POI below zoom. */
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_label_new(_("Show POI below zoom")),
+                0, 1, 2, 3, GTK_FILL, 0, 2, 4);
+        gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+        gtk_table_attach(GTK_TABLE(table),
+                label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
+                1, 2, 2, 3, GTK_FILL, 0, 2, 4);
+        gtk_container_add(GTK_CONTAINER(label),
+                num_poi_zoom = hildon_number_editor_new(0, MAX_ZOOM));
+
+        /* Connect signals. */
+        scan_info.settings_dialog = dialog;
+        scan_info.txt_gps_bt_mac = txt_gps_bt_mac;
+        g_signal_connect(G_OBJECT(btn_scan), "clicked",
+                         G_CALLBACK(scan_bluetooth), &scan_info);
+        g_signal_connect(G_OBJECT(btn_buttons), "clicked",
+                         G_CALLBACK(settings_dialog_hardkeys), dialog);
+        g_signal_connect(G_OBJECT(btn_colors), "clicked",
+                         G_CALLBACK(settings_dialog_colors), dialog);
+
+        poi_browse_info.dialog = dialog;
+        poi_browse_info.txt = txt_poi_db;
+        g_signal_connect(G_OBJECT(btn_browse_poi), "clicked",
+                G_CALLBACK(settings_dialog_browse_forfile), &poi_browse_info);
+
+        gps_file_browse_info.dialog = dialog;
+        gps_file_browse_info.txt = txt_gps_file_path;
+        g_signal_connect(G_OBJECT(btn_browse_gps), "clicked",
+                G_CALLBACK(settings_dialog_browse_forfile),
+                &gps_file_browse_info);
+    }
+
+
+    /* Initialize fields. */
+    if(_gri.bt_mac)
+        gtk_entry_set_text(GTK_ENTRY(txt_gps_bt_mac), _gri.bt_mac);
+    if(_gri.gpsd_host)
+        gtk_entry_set_text(GTK_ENTRY(txt_gps_gpsd_host), _gri.gpsd_host);
+    hildon_number_editor_set_value(
+            HILDON_NUMBER_EDITOR(num_gps_gpsd_port), _gri.gpsd_port);
+    if(_gri.file_path)
+        gtk_entry_set_text(GTK_ENTRY(txt_gps_file_path), _gri.file_path);
+    switch(_gri.type)
+    {
+        case GPS_RCVR_GPSD:
+            gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rad_gps_gpsd),TRUE);
+            break;
+        case GPS_RCVR_FILE:
+            gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rad_gps_file),TRUE);
+            break;
+        default: /* Including GPS_RCVR_BT */
+            gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rad_gps_bt), TRUE);
+            break;
+    }
+
+    if(_poi_db_filename)
+        gtk_entry_set_text(GTK_ENTRY(txt_poi_db), _poi_db_filename);
+    hildon_number_editor_set_value(HILDON_NUMBER_EDITOR(num_poi_zoom),
+            _poi_zoom);
+    hildon_controlbar_set_value(HILDON_CONTROLBAR(num_center_ratio),
+            _center_ratio);
+    hildon_controlbar_set_value(HILDON_CONTROLBAR(num_lead_ratio),
+            _lead_ratio);
+    gtk_toggle_button_set_active(
+            GTK_TOGGLE_BUTTON(chk_lead_is_fixed), _lead_is_fixed);
+    hildon_controlbar_set_value(HILDON_CONTROLBAR(num_rotate_sens),
+            _rotate_sens);
+    gtk_combo_box_set_active(GTK_COMBO_BOX(cmb_rotate_dir), _rotate_dir);
+    hildon_controlbar_set_value(HILDON_CONTROLBAR(num_announce_notice),
+            _announce_notice_ratio);
+    hildon_controlbar_set_value(HILDON_CONTROLBAR(num_draw_width),
+            _draw_width);
+    gtk_combo_box_set_active(GTK_COMBO_BOX(cmb_units), _units);
+    gtk_combo_box_set_active(GTK_COMBO_BOX(cmb_degformat), _degformat);
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chk_speed_limit_on),
+            _speed_limit_on);
+    hildon_controlbar_set_value(HILDON_CONTROLBAR(num_auto_download_precache),
+            _auto_download_precache);
+    hildon_number_editor_set_value(HILDON_NUMBER_EDITOR(num_speed),
+            _speed_limit);
+    gtk_combo_box_set_active(GTK_COMBO_BOX(cmb_speed_location),
+            _speed_location);
+    gtk_combo_box_set_active(GTK_COMBO_BOX(cmb_unblank_option),
+            _unblank_option);
+    gtk_combo_box_set_active(GTK_COMBO_BOX(cmb_info_font_size),
+            _info_font_size);
+
+    gtk_widget_show_all(dialog);
+
+    while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
+    {
+        GpsRcvrType new_grtype;
+
+        /* Set _gri.bt_mac if necessary. */
+        if(!*gtk_entry_get_text(GTK_ENTRY(txt_gps_bt_mac)))
+        {
+            /* User specified no rcvr mac - set _gri.bt_mac to NULL. */
+            if(_gri.bt_mac)
+            {
+                g_free(_gri.bt_mac);
+                _gri.bt_mac = NULL;
+                rcvr_changed = (_gri.type == GPS_RCVR_BT);
+            }
+        }
+        else if(!_gri.bt_mac || strcmp(_gri.bt_mac,
+                      gtk_entry_get_text(GTK_ENTRY(txt_gps_bt_mac))))
+        {
+            /* User specified a new rcvr mac. */
+            g_free(_gri.bt_mac);
+            _gri.bt_mac = g_strdup(gtk_entry_get_text(
+                        GTK_ENTRY(txt_gps_bt_mac)));
+            rcvr_changed = (_gri.type == GPS_RCVR_BT);
+        }
+
+        /* Set _gri.gpsd_host if necessary. */
+        if(!*gtk_entry_get_text(GTK_ENTRY(txt_gps_gpsd_host)))
+        {
+            /* User specified no rcvr mac - set _gri.gpsd_host to NULL. */
+            if(_gri.gpsd_host)
+            {
+                g_free(_gri.gpsd_host);
+                _gri.gpsd_host = NULL;
+                rcvr_changed = (_gri.type == GPS_RCVR_GPSD);
+            }
+        }
+        else if(!_gri.gpsd_host || strcmp(_gri.gpsd_host,
+                      gtk_entry_get_text(GTK_ENTRY(txt_gps_gpsd_host))))
+        {
+            /* User specified a new rcvr mac. */
+            g_free(_gri.gpsd_host);
+            _gri.gpsd_host = g_strdup(gtk_entry_get_text(
+                        GTK_ENTRY(txt_gps_gpsd_host)));
+            rcvr_changed = (_gri.type == GPS_RCVR_GPSD);
+        }
+
+        if(_gri.gpsd_port != hildon_number_editor_get_value(
+                    HILDON_NUMBER_EDITOR(num_gps_gpsd_port)))
+        {
+            _gri.gpsd_port = hildon_number_editor_get_value(
+                    HILDON_NUMBER_EDITOR(num_gps_gpsd_port));
+            rcvr_changed = (_gri.type == GPS_RCVR_GPSD);
+        }
+
+        /* Set _gri.file_path if necessary. */
+        if(!*gtk_entry_get_text(GTK_ENTRY(txt_gps_file_path)))
+        {
+            /* User specified no rcvr mac - set _gri.file_path to NULL. */
+            if(_gri.file_path)
+            {
+                g_free(_gri.file_path);
+                _gri.file_path = NULL;
+                rcvr_changed = (_gri.type == GPS_RCVR_FILE);
+            }
+        }
+        else if(!_gri.file_path || strcmp(_gri.file_path,
+                      gtk_entry_get_text(GTK_ENTRY(txt_gps_file_path))))
+        {
+            /* User specified a new rcvr mac. */
+            g_free(_gri.file_path);
+            _gri.file_path = g_strdup(gtk_entry_get_text(
+                        GTK_ENTRY(txt_gps_file_path)));
+            rcvr_changed = (_gri.type == GPS_RCVR_FILE);
+        }
+
+        if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rad_gps_bt)))
+            new_grtype = _gri.bt_mac ? GPS_RCVR_BT : GPS_RCVR_NONE;
+        else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rad_gps_gpsd)))
+            new_grtype = _gri.gpsd_host ? GPS_RCVR_GPSD : GPS_RCVR_NONE;
+        else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rad_gps_file)))
+            new_grtype = _gri.file_path ? GPS_RCVR_FILE : GPS_RCVR_NONE;
+        else
+            new_grtype = GPS_RCVR_NONE;
+
+        if(new_grtype != _gri.type)
+        {
+            _gri.type = new_grtype;
+            rcvr_changed = TRUE;
+        }
+
+        if(_gri.type != GPS_RCVR_NONE)
+        {
+            gtk_widget_set_sensitive(
+                    GTK_WIDGET(_menu_gps_details_item), FALSE);
+        }
+        else
+        {
+            if(_enable_gps)
+            {
+                gtk_check_menu_item_set_active(
+                        GTK_CHECK_MENU_ITEM(_menu_enable_gps_item), FALSE);
+                popup_error(dialog, _("No GPS Receiver provided.\n"
+                        "GPS will be disabled."));
+                rcvr_changed = TRUE;
+                gtk_widget_set_sensitive(GTK_WIDGET(_menu_gps_details_item),
+                        FALSE);
+                gtk_widget_set_sensitive(GTK_WIDGET(_menu_gps_reset_item),
+                        FALSE);
+            }
+        }
+
+        _center_ratio = hildon_controlbar_get_value(
+                HILDON_CONTROLBAR(num_center_ratio));
+
+        _lead_ratio = hildon_controlbar_get_value(
+                HILDON_CONTROLBAR(num_lead_ratio));
+
+        _lead_is_fixed = gtk_toggle_button_get_active(
+                GTK_TOGGLE_BUTTON(chk_lead_is_fixed));
+
+        _rotate_sens = hildon_controlbar_get_value(
+                HILDON_CONTROLBAR(num_rotate_sens));
+
+        _rotate_dir = gtk_combo_box_get_active(GTK_COMBO_BOX(cmb_rotate_dir));
+
+        _auto_download_precache = hildon_controlbar_get_value(
+                HILDON_CONTROLBAR(num_auto_download_precache));
+
+        _draw_width = hildon_controlbar_get_value(
+                HILDON_CONTROLBAR(num_draw_width));
+
+        _units = gtk_combo_box_get_active(GTK_COMBO_BOX(cmb_units));
+        _degformat = gtk_combo_box_get_active(GTK_COMBO_BOX(cmb_degformat));
+
+        _speed_limit_on = gtk_toggle_button_get_active(
+                GTK_TOGGLE_BUTTON(chk_speed_limit_on));
+        _speed_limit = hildon_number_editor_get_value(
+                HILDON_NUMBER_EDITOR(num_speed));
+        _speed_location = gtk_combo_box_get_active(
+                GTK_COMBO_BOX(cmb_speed_location));
+
+        _unblank_option = gtk_combo_box_get_active(
+                GTK_COMBO_BOX(cmb_unblank_option));
+
+        _info_font_size = gtk_combo_box_get_active(
+                GTK_COMBO_BOX(cmb_info_font_size));
+
+        _announce_notice_ratio = hildon_controlbar_get_value(
+                HILDON_CONTROLBAR(num_announce_notice));
+
+        _enable_voice = gtk_toggle_button_get_active(
+                GTK_TOGGLE_BUTTON(chk_enable_voice));
+
+        /* Check if user specified a different POI database from before. */
+        if((!_poi_db_filename && *gtk_entry_get_text(GTK_ENTRY(txt_poi_db)))
+                || strcmp(_poi_db_filename,
+                    gtk_entry_get_text(GTK_ENTRY(txt_poi_db))))
+        {
+            /* Clear old filename/dirname, if necessary. */
+            if(_poi_db_filename)
+            {
+                g_free(_poi_db_filename);
+                _poi_db_filename = NULL;
+                g_free(_poi_db_dirname);
+                _poi_db_dirname = NULL;
+            }
+
+            if(*gtk_entry_get_text(GTK_ENTRY(txt_poi_db)))
+            {
+                _poi_db_filename = g_strdup(gtk_entry_get_text(
+                            GTK_ENTRY(txt_poi_db)));
+                _poi_db_dirname = g_path_get_dirname(_poi_db_filename);
+            }
+
+            poi_db_connect();
+        }
+
+        _poi_zoom = hildon_number_editor_get_value(
+                HILDON_NUMBER_EDITOR(num_poi_zoom));
+
+        update_gcs();
+
+        settings_save();
+
+        map_force_redraw();
+        map_refresh_mark(TRUE);
+
+        break;
+    }
+
+    gtk_widget_hide(dialog);
+
+    vprintf("%s(): return %d\n", __PRETTY_FUNCTION__, rcvr_changed);
+    return rcvr_changed;
+}
+
+RepoData*
+settings_parse_repo(gchar *str)
+{
+    /* Parse each part of a repo, delimited by newline characters:
+     * 1. name
+     * 2. url
+     * 3. db_filename
+     * 4. dl_zoom_steps
+     * 5. view_zoom_steps
+     */
+    gchar *token, *error_check;
+    printf("%s(%s)\n", __PRETTY_FUNCTION__, str);
+
+    RepoData *rd = g_new0(RepoData, 1);
+
+    /* Parse name. */
+    token = strsep(&str, "\n\t");
+    if(token)
+        rd->name = g_strdup(token);
+
+    /* Parse URL format. */
+    token = strsep(&str, "\n\t");
+    if(token)
+        rd->url = g_strdup(token);
+
+    /* Parse cache dir. */
+    token = strsep(&str, "\n\t");
+    if(token)
+        rd->db_filename = gnome_vfs_expand_initial_tilde(token);
+
+    /* Parse download zoom steps. */
+    token = strsep(&str, "\n\t");
+    if(!token || !*token || !(rd->dl_zoom_steps = atoi(token)))
+        rd->dl_zoom_steps = 2;
+
+    /* Parse view zoom steps. */
+    token = strsep(&str, "\n\t");
+    if(!token || !*token || !(rd->view_zoom_steps = atoi(token)))
+        rd->view_zoom_steps = 1;
+
+    /* Parse double-size. */
+    token = strsep(&str, "\n\t");
+    if(token)
+        rd->double_size = atoi(token); /* Default is zero (FALSE) */
+
+    /* Parse next-able. */
+    token = strsep(&str, "\n\t");
+    if(!token || !*token
+            || (rd->nextable = strtol(token, &error_check, 10), token == str))
+        rd->nextable = TRUE;
+
+    set_repo_type(rd);
+
+    vprintf("%s(): return %p\n", __PRETTY_FUNCTION__, rd);
+    return rd;
+}
+
+/**
+ * Initialize all configuration from GCONF.  This should not be called more
+ * than once during execution.
+ */
+void
+settings_init()
+{
+    GConfValue *value;
+    GConfClient *gconf_client = gconf_client_get_default();
+    gchar *str;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    if(!gconf_client)
+    {
+        popup_error(_window, _("Failed to initialize GConf.  Quitting."));
+        exit(1);
+    }
+
+    /* Get GPS Receiver Type.  Default is Bluetooth Receiver. */
+    {
+        gchar *gri_type_str = gconf_client_get_string(gconf_client,
+                GCONF_KEY_GPS_RCVR_TYPE, NULL);
+        gint i = 0;
+        if(gri_type_str)
+            for(i = GPS_RCVR_ENUM_COUNT - 1; i > 0; i--)
+                if(!strcmp(gri_type_str, GPS_RCVR_ENUM_TEXT[i]))
+                    break;
+        _gri.type = i;
+    }
+
+    /* Get Bluetooth Receiver MAC.  Default is NULL. */
+    _gri.bt_mac = gconf_client_get_string(
+            gconf_client, GCONF_KEY_GPS_BT_MAC, NULL);
+
+    /* Get Bluetooth Receiver File.  Default is NULL. */
+    _gri.bt_file = gconf_client_get_string(
+            gconf_client, GCONF_KEY_GPS_BT_FILE, NULL);
+
+    /* Get GPSD Host.  Default is NULL. */
+    _gri.gpsd_host = gconf_client_get_string(
+            gconf_client, GCONF_KEY_GPS_GPSD_HOST, NULL);
+
+    /* Get GPSD Port.  Default is 2947. */
+    if(!(_gri.gpsd_port = gconf_client_get_int(
+            gconf_client, GCONF_KEY_GPS_GPSD_PORT, NULL)))
+        _gri.gpsd_port = 2947;
+
+    /* Get File Path.  Default is NULL. */
+    _gri.file_path = gconf_client_get_string(
+            gconf_client, GCONF_KEY_GPS_FILE_PATH, NULL);
+
+    /* Get Auto-Download.  Default is FALSE. */
+    _auto_download = gconf_client_get_bool(gconf_client,
+            GCONF_KEY_AUTO_DOWNLOAD, NULL);
+
+    /* Get Auto-Download Pre-cache - Default is 2. */
+    _auto_download_precache = gconf_client_get_int(gconf_client,
+            GCONF_KEY_AUTO_DOWNLOAD_PRECACHE, NULL);
+    if(!_auto_download_precache)
+        _auto_download_precache = 2;
+
+    /* Get Center Ratio - Default is 5. */
+    _center_ratio = gconf_client_get_int(gconf_client,
+            GCONF_KEY_CENTER_SENSITIVITY, NULL);
+    if(!_center_ratio)
+        _center_ratio = 5;
+
+    /* Get Lead Ratio - Default is 5. */
+    _lead_ratio = gconf_client_get_int(gconf_client,
+            GCONF_KEY_LEAD_AMOUNT, NULL);
+    if(!_lead_ratio)
+        _lead_ratio = 5;
+
+    /* Get Lead Is Fixed flag - Default is FALSE. */
+    _lead_is_fixed = gconf_client_get_bool(gconf_client,
+            GCONF_KEY_LEAD_IS_FIXED, NULL);
+
+    /* Get Rotate Sensitivity - Default is 5. */
+    _rotate_sens = gconf_client_get_int(gconf_client,
+            GCONF_KEY_ROTATE_SENSITIVITY, NULL);
+    if(!_rotate_sens)
+        _rotate_sens = 5;
+
+    /* Get Rotate Dir - Default is ROTATE_DIR_UP. */
+    {
+        gchar *rotate_dir_str = gconf_client_get_string(gconf_client,
+                GCONF_KEY_ROTATE_DIR, NULL);
+        gint i = -1;
+        if(rotate_dir_str)
+            for(i = ROTATE_DIR_ENUM_COUNT - 1; i >= 0; i--)
+                if(!strcmp(rotate_dir_str, ROTATE_DIR_ENUM_TEXT[i]))
+                    break;
+        if(i == -1)
+            i = ROTATE_DIR_UP;
+        _rotate_dir = i;
+    }
+
+    /* Get Draw Line Width- Default is 5. */
+    _draw_width = gconf_client_get_int(gconf_client,
+            GCONF_KEY_DRAW_WIDTH, NULL);
+    if(!_draw_width)
+        _draw_width = 5;
+
+    /* Get Announce Advance Notice - Default is 30. */
+    value = gconf_client_get(gconf_client, GCONF_KEY_ANNOUNCE_NOTICE, NULL);
+    if(value)
+    {
+        _announce_notice_ratio = gconf_value_get_int(value);
+        gconf_value_free(value);
+    }
+    else
+        _announce_notice_ratio = 8;
+
+    /* Get Enable Voice flag.  Default is TRUE. */
+    value = gconf_client_get(gconf_client, GCONF_KEY_ENABLE_VOICE, NULL);
+    if(value)
+    {
+        _enable_voice = gconf_value_get_bool(value);
+        gconf_value_free(value);
+    }
+    else
+        _enable_voice = TRUE;
+
+    /* Get Fullscreen flag. Default is FALSE. */
+    _fullscreen = gconf_client_get_bool(gconf_client,
+            GCONF_KEY_FULLSCREEN, NULL);
+
+    /* Get Units.  Default is UNITS_KM. */
+    {
+        gchar *units_str = gconf_client_get_string(gconf_client,
+                GCONF_KEY_UNITS, NULL);
+        gint i = 0;
+        if(units_str)
+            for(i = UNITS_ENUM_COUNT - 1; i > 0; i--)
+                if(!strcmp(units_str, UNITS_ENUM_TEXT[i]))
+                    break;
+        _units = i;
+    }
+
+    /* Get Custom Key Actions. */
+    {
+        gint i;
+        for(i = 0; i < CUSTOM_KEY_ENUM_COUNT; i++)
+        {
+            gint j = CUSTOM_KEY_DEFAULT[i];
+            gchar *str = gconf_client_get_string(gconf_client,
+                    CUSTOM_KEY_GCONF[i], NULL);
+            if(str)
+                for(j = CUSTOM_ACTION_ENUM_COUNT - 1; j > 0; j--)
+                    if(!strcmp(str, CUSTOM_ACTION_ENUM_TEXT[j]))
+                        break;
+            _action[i] = j;
+        }
+    }
+
+    /* Get Deg format.  Default is DDPDDDDD. */
+    {
+        gchar *degformat_key_str = gconf_client_get_string(gconf_client,
+                GCONF_KEY_DEG_FORMAT, NULL);
+        gint i = 0;
+        if(degformat_key_str)
+            for(i = DEG_FORMAT_ENUM_COUNT - 1; i > 0; i--)
+                if(!strcmp(degformat_key_str, DEG_FORMAT_ENUM_TEXT[i]))
+                    break;
+        _degformat = i;
+    }
+
+    /* Get Speed Limit On flag.  Default is FALSE. */
+    _speed_limit_on = gconf_client_get_bool(gconf_client,
+            GCONF_KEY_SPEED_LIMIT_ON, NULL);
+
+    /* Get Speed Limit */
+    _speed_limit = gconf_client_get_int(gconf_client,
+            GCONF_KEY_SPEED_LIMIT, NULL);
+    if(_speed_limit <= 0)
+        _speed_limit = 100;
+
+    /* Get Speed Location.  Default is SPEED_LOCATION_TOP_LEFT. */
+    {
+        gchar *speed_location_str = gconf_client_get_string(gconf_client,
+                GCONF_KEY_SPEED_LOCATION, NULL);
+        gint i = 0;
+        if(speed_location_str)
+            for(i = SPEED_LOCATION_ENUM_COUNT - 1; i > 0; i--)
+                if(!strcmp(speed_location_str, SPEED_LOCATION_ENUM_TEXT[i]))
+                    break;
+        _speed_location = i;
+    }
+
+    /* Get Unblank Option.  Default is UNBLANK_FULLSCREEN. */
+    {
+        gchar *unblank_option_str = gconf_client_get_string(gconf_client,
+                GCONF_KEY_UNBLANK_SIZE, NULL);
+        gint i = -1;
+        if(unblank_option_str)
+            for(i = UNBLANK_ENUM_COUNT - 1; i >= 0; i--)
+                if(!strcmp(unblank_option_str, UNBLANK_ENUM_TEXT[i]))
+                    break;
+        if(i == -1)
+            i = UNBLANK_FULLSCREEN;
+        _unblank_option = i;
+    }
+
+    /* Get Info Font Size.  Default is INFO_FONT_MEDIUM. */
+    {
+        gchar *info_font_size_str = gconf_client_get_string(gconf_client,
+                GCONF_KEY_INFO_FONT_SIZE, NULL);
+        gint i = -1;
+        if(info_font_size_str)
+            for(i = INFO_FONT_ENUM_COUNT - 1; i >= 0; i--)
+                if(!strcmp(info_font_size_str, INFO_FONT_ENUM_TEXT[i]))
+                    break;
+        if(i == -1)
+            i = INFO_FONT_MEDIUM;
+        _info_font_size = i;
+    }
+
+    /* Get last saved latitude.  Default is 50.f. */
+    value = gconf_client_get(gconf_client, GCONF_KEY_LAST_LAT, NULL);
+    if(value)
+    {
+        _gps.lat = gconf_value_get_float(value);
+        gconf_value_free(value);
+    }
+    else
+        _gps.lat = 50.f;
+
+    /* Get last saved longitude.  Default is 0. */
+    _gps.lon = gconf_client_get_float(gconf_client, GCONF_KEY_LAST_LON, NULL);
+
+    /* Get last saved altitude.  Default is 0. */
+    _pos.altitude = gconf_client_get_int(
+            gconf_client, GCONF_KEY_LAST_ALT, NULL);
+
+    /* Get last saved speed.  Default is 0. */
+    _gps.speed = gconf_client_get_float(
+            gconf_client, GCONF_KEY_LAST_SPEED, NULL);
+
+    /* Get last saved speed.  Default is 0. */
+    _gps.heading = gconf_client_get_float(
+            gconf_client, GCONF_KEY_LAST_HEADING, NULL);
+
+    /* Get last saved timestamp.  Default is 0. */
+    _pos.time= gconf_client_get_float(gconf_client, GCONF_KEY_LAST_TIME, NULL);
+
+    /* Get last center point. */
+    {
+        gfloat center_lat, center_lon;
+
+        /* Get last saved latitude.  Default is last saved latitude. */
+        value = gconf_client_get(gconf_client, GCONF_KEY_CENTER_LAT, NULL);
+        if(value)
+        {
+            center_lat = gconf_value_get_float(value);
+            gconf_value_free(value);
+        }
+        else
+            center_lat = _gps.lat;
+
+        /* Get last saved longitude.  Default is last saved longitude. */
+        value = gconf_client_get(gconf_client, GCONF_KEY_CENTER_LON, NULL);
+        if(value)
+        {
+            center_lon = gconf_value_get_float(value);
+            gconf_value_free(value);
+        }
+        else
+            center_lon = _gps.lon;
+
+        latlon2unit(center_lat, center_lon, _center.unitx, _center.unity);
+        _next_center = _center;
+    }
+
+    /* Get last viewing angle.  Default is 0. */
+    _map_rotate_angle = _next_map_rotate_angle = gconf_client_get_int(
+            gconf_client, GCONF_KEY_CENTER_ANGLE, NULL);
+    gdk_pixbuf_rotate_matrix_fill_for_rotation(
+            _map_rotate_matrix,
+            deg2rad(ROTATE_DIR_ENUM_DEGREES[_rotate_dir] - _map_rotate_angle));
+    gdk_pixbuf_rotate_matrix_fill_for_rotation(
+            _map_reverse_matrix,
+            deg2rad(_map_rotate_angle - ROTATE_DIR_ENUM_DEGREES[_rotate_dir]));
+
+
+    /* Load the repositories. */
+    {
+        GSList *list, *curr;
+        gint curr_repo_index = gconf_client_get_int(gconf_client,
+            GCONF_KEY_CURRREPO, NULL);
+        list = gconf_client_get_list(gconf_client,
+            GCONF_KEY_REPOSITORIES, GCONF_VALUE_STRING, NULL);
+
+        for(curr = list; curr != NULL; curr = curr->next)
+        {
+            RepoData *rd = settings_parse_repo(curr->data);
+            _repo_list = g_list_append(_repo_list, rd);
+            if(!curr_repo_index--)
+                repo_set_curr(rd);
+            g_free(curr->data);
+        }
+        g_slist_free(list);
+    }
+
+
+    if(_repo_list == NULL)
+    {
+        /* We have no repositories - create a default one. */
+        RepoData *repo = g_new(RepoData, 1);
+
+        repo->db_filename = gnome_vfs_expand_initial_tilde(
+                REPO_DEFAULT_CACHE_DIR);
+        repo->url=g_strdup(REPO_DEFAULT_MAP_URI);
+        repo->dl_zoom_steps = REPO_DEFAULT_DL_ZOOM_STEPS;
+        repo->name = g_strdup(REPO_DEFAULT_NAME);
+        repo->view_zoom_steps = REPO_DEFAULT_VIEW_ZOOM_STEPS;
+        repo->double_size = FALSE;
+        repo->nextable = TRUE;
+        set_repo_type(repo);
+
+        _repo_list = g_list_append(_repo_list, repo);
+        repo_set_curr(repo);
+    }
+
+    /* Get last Zoom Level.  Default is 12. */
+    value = gconf_client_get(gconf_client, GCONF_KEY_ZOOM, NULL);
+    if(value)
+    {
+        _zoom = gconf_value_get_int(value) / _curr_repo->view_zoom_steps
+            * _curr_repo->view_zoom_steps;
+        gconf_value_free(value);
+    }
+    else
+        _zoom = 12 / _curr_repo->view_zoom_steps
+            * _curr_repo->view_zoom_steps;
+    BOUND(_zoom, 0, MAX_ZOOM - 1);
+    _next_zoom = _zoom;
+
+    /* Get Route Directory.  Default is NULL. */
+    _route_dir_uri = gconf_client_get_string(gconf_client,
+            GCONF_KEY_ROUTEDIR, NULL);
+
+    /* Get Last Track File.  Default is NULL. */
+    _track_file_uri = gconf_client_get_string(gconf_client,
+            GCONF_KEY_TRACKFILE, NULL);
+
+    /* Get Auto-Center Mode.  Default is CENTER_LEAD. */
+    value = gconf_client_get(gconf_client, GCONF_KEY_AUTOCENTER_MODE, NULL);
+    if(value)
+    {
+        _center_mode = gconf_value_get_int(value);
+        gconf_value_free(value);
+    }
+    else
+        _center_mode = CENTER_LEAD;
+
+    /* Get Auto-Center Rotate Flag.  Default is TRUE. */
+    value = gconf_client_get(gconf_client, GCONF_KEY_AUTOCENTER_ROTATE, NULL);
+    if(value)
+    {
+        _center_rotate = gconf_value_get_bool(value);
+        gconf_value_free(value);
+    }
+    else
+        _center_rotate = TRUE;
+
+    /* Get Show Zoom Level flag.  Default is FALSE. */
+    _show_zoomlevel = gconf_client_get_bool(gconf_client,
+            GCONF_KEY_SHOWZOOMLEVEL, NULL);
+
+    /* Get Show Scale flag.  Default is TRUE. */
+    value = gconf_client_get(gconf_client, GCONF_KEY_SHOWSCALE, NULL);
+    if(value)
+    {
+        _show_scale = gconf_value_get_bool(value);
+        gconf_value_free(value);
+    }
+    else
+        _show_scale = TRUE;
+
+    /* Get Show Compass Rose flag.  Default is TRUE. */
+    value = gconf_client_get(gconf_client, GCONF_KEY_SHOWCOMPROSE, NULL);
+    if(value)
+    {
+        _show_comprose = gconf_value_get_bool(value);
+        gconf_value_free(value);
+    }
+    else
+        _show_comprose = TRUE;
+
+    /* Get Show Tracks flag.  Default is TRUE. */
+    value = gconf_client_get(gconf_client, GCONF_KEY_SHOWTRACKS, NULL);
+    if(value)
+    {
+        _show_paths |= (gconf_value_get_bool(value) ? TRACKS_MASK : 0);
+        gconf_value_free(value);
+    }
+    else
+        _show_paths |= TRACKS_MASK;
+
+    /* Get Show Routes flag.  Default is TRUE. */
+    value = gconf_client_get(gconf_client, GCONF_KEY_SHOWROUTES, NULL);
+    if(value)
+    {
+        _show_paths |= (gconf_value_get_bool(value) ? ROUTES_MASK : 0);
+        gconf_value_free(value);
+    }
+    else
+        _show_paths |= ROUTES_MASK;
+
+    /* Get Show Velocity Vector flag.  Default is TRUE. */
+    value = gconf_client_get(gconf_client, GCONF_KEY_SHOWVELVEC, NULL);
+    if(value)
+    {
+        _show_velvec = gconf_value_get_bool(value);
+        gconf_value_free(value);
+    }
+    else
+        _show_velvec = TRUE;
+
+    /* Get Show Velocity Vector flag.  Default is TRUE. */
+    value = gconf_client_get(gconf_client, GCONF_KEY_SHOWPOIS, NULL);
+    if(value)
+    {
+        _show_poi = gconf_value_get_bool(value);
+        gconf_value_free(value);
+    }
+    else
+        _show_poi = TRUE;
+
+    /* Get Enable GPS flag.  Default is TRUE. */
+    value = gconf_client_get(gconf_client, GCONF_KEY_ENABLE_GPS, NULL);
+    if(value)
+    {
+        _enable_gps = gconf_value_get_bool(value);
+        gconf_value_free(value);
+    }
+    else
+        _enable_gps = TRUE;
+
+    /* Initialize _gps_state based on _enable_gps. */
+    _gps_state = RCVR_OFF;
+
+    /* Load the route locations. */
+    {
+        GSList *curr;
+        _loc_list = gconf_client_get_list(gconf_client,
+            GCONF_KEY_ROUTE_LOCATIONS, GCONF_VALUE_STRING, NULL);
+        _loc_model = gtk_list_store_new(1, G_TYPE_STRING);
+        for(curr = _loc_list; curr != NULL; curr = curr->next)
+        {
+            GtkTreeIter iter;
+            gtk_list_store_insert_with_values(_loc_model, &iter, INT_MAX,
+                    0, curr->data, -1);
+        }
+    }
+
+    /* Get POI Database.  Default is in REPO_DEFAULT_CACHE_BASE */
+    _poi_db_filename = gconf_client_get_string(gconf_client,
+            GCONF_KEY_POI_DB, NULL);
+    if(_poi_db_filename == NULL)
+    {
+        gchar *poi_base = gnome_vfs_expand_initial_tilde(
+                REPO_DEFAULT_CACHE_BASE);
+        _poi_db_filename = gnome_vfs_uri_make_full_from_relative(
+                poi_base, "poi.db");
+        g_free(poi_base);
+    }
+
+    _poi_zoom = gconf_client_get_int(gconf_client,
+            GCONF_KEY_POI_ZOOM, NULL);
+    if(!_poi_zoom)
+    _poi_zoom = 6;
+
+
+    /* Get GPS Info flag.  Default is FALSE. */
+    _gps_info = gconf_client_get_bool(gconf_client, GCONF_KEY_GPS_INFO, NULL);
+
+    /* Get Route Download URL.  Default is:
+     * "http://www.gnuite.com/cgi-bin/gpx.cgi?saddr=%s&daddr=%s" */
+    _route_dl_url = gconf_client_get_string(gconf_client,
+            GCONF_KEY_ROUTE_DL_URL, NULL);
+    if(_route_dl_url == NULL)
+        _route_dl_url = g_strdup(
+                "http://www.gnuite.com/cgi-bin/gpx.cgi?saddr=%s&daddr=%s");
+
+    /* Get Route Download Radius.  Default is 4. */
+    value = gconf_client_get(gconf_client, GCONF_KEY_ROUTE_DL_RADIUS, NULL);
+    if(value)
+    {
+        _route_dl_radius = gconf_value_get_int(value);
+        gconf_value_free(value);
+    }
+    else
+        _route_dl_radius = 4;
+
+    /* Get POI Download URL.  Default is:
+     * "http://www.gnuite.com/cgi-bin/poi.cgi?saddr=%s&query=%s&page=%d" */
+    _poi_dl_url = gconf_client_get_string(gconf_client,
+            GCONF_KEY_POI_DL_URL, NULL);
+    if(_poi_dl_url == NULL)
+        _poi_dl_url = g_strdup(
+            "http://www.gnuite.com/cgi-bin/poi.cgi?saddr=%s&query=%s&page=%d");
+
+    /* Get Colors. */
+    {
+        gint i;
+        for(i = 0; i < COLORABLE_ENUM_COUNT; i++)
+        {
+            str = gconf_client_get_string(gconf_client,
+                    COLORABLE_GCONF[i], NULL);
+            if(!str || !gdk_color_parse(str, &_color[i]))
+                _color[i] = COLORABLE_DEFAULT[i];
+        }
+    }
+
+    gconf_client_clear_cache(gconf_client);
+    g_object_unref(gconf_client);
+
+    /* GPS data init */
+    _gps.fix = 1;
+    _gps.satinuse = 0;
+    _gps.satinview = 0;
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
diff --git a/src/settings.h b/src/settings.h
new file mode 100644 (file)
index 0000000..b258244
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAEMO_MAPPER_SETTINGS_H
+#define MAEMO_MAPPER_SETTINGS_H
+
+#include <dbus/dbus-glib.h>
+
+typedef struct _ScanInfo ScanInfo;
+struct _ScanInfo {
+    GtkWidget *settings_dialog;
+    GtkWidget *txt_gps_bt_mac;
+    GtkWidget *scan_dialog;
+    GtkWidget *banner;
+    GtkListStore *store;
+    gint sid;
+    DBusGProxy *req_proxy;
+    DBusGProxy *sig_proxy;
+};
+
+typedef struct _KeysDialogInfo KeysDialogInfo;
+struct _KeysDialogInfo {
+    GtkWidget *cmb[CUSTOM_KEY_ENUM_COUNT];
+};
+
+typedef struct _ColorsDialogInfo ColorsDialogInfo;
+struct _ColorsDialogInfo {
+    GtkWidget *col[COLORABLE_ENUM_COUNT];
+};
+
+
+RepoData* settings_parse_repo(gchar *str);
+
+void settings_init();
+void settings_save();
+
+gboolean settings_dialog();
+
+#endif /* ifndef MAEMO_MAPPER_SETTINGS_H */
diff --git a/src/types.h b/src/types.h
new file mode 100644 (file)
index 0000000..2e236c9
--- /dev/null
@@ -0,0 +1,495 @@
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAEMO_MAPPER_TYPES_H
+#define MAEMO_MAPPER_TYPES_H
+
+#include <time.h>
+#include <gdbm.h>
+#include <gtk/gtk.h>
+#include <libgnomevfs/gnome-vfs.h>
+
+#define _(String) gettext(String)
+
+/** This enumerated type defines the possible connection states. */
+typedef enum
+{
+    /** The receiver is "off", meaning that either the bluetooth radio is
+     * off or the user has requested not to connect to the GPS receiver.
+     * No gtk_banner is visible. */
+    RCVR_OFF,
+
+    /** We are now trying to disconnect from the receiver. */
+    RCVR_DISCONNECT,
+
+    /** The connection with the receiver is down.  A gtk_banner is visible with
+     * the text, "Connecting to GPS receiver". */
+    RCVR_DOWN,
+
+    /** The connection with the receiver is up, but a GPS fix is not available.
+     * A gtk_banner is visible with the text, "(Re-)Establishing GPS fix". */
+    RCVR_UP,
+
+    /** The connection with the receiver is up and a GPS fix IS available.
+     * No gtk_banner is visible. */
+    RCVR_FIXED
+} ConnState;
+
+/** This enumerated type defines the supported types of repositories. */
+typedef enum
+{
+    REPOTYPE_NONE, /* No URL set. */
+    REPOTYPE_XYZ, /* x=%d, y=%d, and zoom=%d */
+    REPOTYPE_XYZ_INV, /* zoom=%0d, x=%d, y=%d */
+    REPOTYPE_QUAD_QRST, /* t=%s   (%s = {qrst}*) */
+    REPOTYPE_QUAD_ZERO, /* t=%0s  (%0s = {0123}*) */
+    REPOTYPE_WMS        /* "service=wms" */
+} RepoType;
+
+/** Possible center modes.  The "WAS" modes imply no current center mode;
+ * they only hint at what the last center mode was, so that it can be
+ * recalled. */
+typedef enum
+{
+    CENTER_WAS_LATLON = -2,
+    CENTER_WAS_LEAD = -1,
+    CENTER_LEAD = 1,
+    CENTER_LATLON = 2
+} CenterMode;
+
+/** This enum defines the states of the SAX parsing state machine. */
+typedef enum
+{
+    START,
+    INSIDE_GPX,
+    INSIDE_WPT,
+    INSIDE_WPT_NAME,
+    INSIDE_WPT_DESC,
+    INSIDE_PATH,
+    INSIDE_PATH_SEGMENT,
+    INSIDE_PATH_POINT,
+    INSIDE_PATH_POINT_ELE,
+    INSIDE_PATH_POINT_TIME,
+    INSIDE_PATH_POINT_DESC,
+    FINISH,
+    UNKNOWN,
+    ERROR,
+} SaxState;
+
+/** POI dialog action **/
+typedef enum
+{
+    ACTION_ADD_POI,
+    ACTION_EDIT_POI,
+} POIAction;
+
+/** Category list **/
+typedef enum
+{
+    CAT_ID,
+    CAT_ENABLED,
+    CAT_LABEL,
+    CAT_DESC,
+    CAT_POI_CNT,
+    CAT_NUM_COLUMNS
+} CategoryList;
+
+/** POI list **/
+typedef enum
+{
+    POI_SELECTED,
+    POI_POIID,
+    POI_CATID,
+    POI_LAT,
+    POI_LON,
+    POI_LATLON,
+    POI_BEARING,
+    POI_DISTANCE,
+    POI_LABEL,
+    POI_DESC,
+    POI_CLABEL,
+    POI_NUM_COLUMNS
+} POIList;
+
+/** This enum defines the possible units we can use. */
+typedef enum
+{
+    UNITS_KM,
+    UNITS_MI,
+    UNITS_NM,
+    UNITS_ENUM_COUNT
+} UnitType;
+
+typedef enum
+{
+    UNBLANK_WITH_GPS,
+    UNBLANK_WHEN_MOVING,
+    UNBLANK_FULLSCREEN,
+    UNBLANK_WAYPOINT,
+    UNBLANK_NEVER,
+    UNBLANK_ENUM_COUNT
+} UnblankOption;
+
+/** This enum defines the possible font sizes. */
+typedef enum
+{
+    INFO_FONT_XXSMALL,
+    INFO_FONT_XSMALL,
+    INFO_FONT_SMALL,
+    INFO_FONT_MEDIUM,
+    INFO_FONT_LARGE,
+    INFO_FONT_XLARGE,
+    INFO_FONT_XXLARGE,
+    INFO_FONT_ENUM_COUNT
+} InfoFontSize;
+
+/** This enum defines the possible font sizes. */
+typedef enum
+{
+    ROTATE_DIR_UP,
+    ROTATE_DIR_RIGHT,
+    ROTATE_DIR_DOWN,
+    ROTATE_DIR_LEFT,
+    ROTATE_DIR_ENUM_COUNT
+} RotateDir;
+
+/** This enum defines all of the key-customizable actions. */
+typedef enum
+{
+    CUSTOM_ACTION_PAN_NORTH,
+    CUSTOM_ACTION_PAN_WEST,
+    CUSTOM_ACTION_PAN_SOUTH,
+    CUSTOM_ACTION_PAN_EAST,
+    CUSTOM_ACTION_RESET_VIEW_ANGLE,
+    CUSTOM_ACTION_ROTATE_CLOCKWISE,
+    CUSTOM_ACTION_ROTATE_COUNTERCLOCKWISE,
+    CUSTOM_ACTION_TOGGLE_AUTOCENTER,
+    CUSTOM_ACTION_TOGGLE_AUTOROTATE,
+    CUSTOM_ACTION_ZOOM_IN,
+    CUSTOM_ACTION_ZOOM_OUT,
+    CUSTOM_ACTION_TOGGLE_FULLSCREEN,
+    CUSTOM_ACTION_TOGGLE_TRACKS,
+    CUSTOM_ACTION_TOGGLE_SCALE,
+    CUSTOM_ACTION_TOGGLE_POI,
+    CUSTOM_ACTION_CHANGE_REPO,
+    CUSTOM_ACTION_ROUTE_DISTNEXT,
+    CUSTOM_ACTION_ROUTE_DISTLAST,
+    CUSTOM_ACTION_TRACK_BREAK,
+    CUSTOM_ACTION_TRACK_CLEAR,
+    CUSTOM_ACTION_TRACK_DISTLAST,
+    CUSTOM_ACTION_TRACK_DISTFIRST,
+    CUSTOM_ACTION_TOGGLE_GPS,
+    CUSTOM_ACTION_TOGGLE_GPSINFO,
+    CUSTOM_ACTION_TOGGLE_SPEEDLIMIT,
+    CUSTOM_ACTION_RESET_BLUETOOTH,
+    CUSTOM_ACTION_ENUM_COUNT
+} CustomAction;
+
+/** This enum defines all of the customizable keys. */
+typedef enum
+{
+    CUSTOM_KEY_UP,
+    CUSTOM_KEY_LEFT,
+    CUSTOM_KEY_DOWN,
+    CUSTOM_KEY_RIGHT,
+    CUSTOM_KEY_SELECT,
+    CUSTOM_KEY_INCREASE,
+    CUSTOM_KEY_DECREASE,
+    CUSTOM_KEY_FULLSCREEN,
+    CUSTOM_KEY_ESC,
+    CUSTOM_KEY_ENUM_COUNT
+} CustomKey;
+
+/** This enum defines all of the colorable objects. */
+typedef enum
+{
+    COLORABLE_MARK,
+    COLORABLE_MARK_VELOCITY,
+    COLORABLE_MARK_OLD,
+    COLORABLE_TRACK,
+    COLORABLE_TRACK_MARK,
+    COLORABLE_TRACK_BREAK,
+    COLORABLE_ROUTE,
+    COLORABLE_ROUTE_WAY,
+    COLORABLE_ROUTE_BREAK,
+    COLORABLE_POI,
+    COLORABLE_ENUM_COUNT
+} Colorable;
+
+typedef enum
+{
+    DDPDDDDD,
+    DD_MMPMMM,
+    DD_MM_SSPS,
+    DDPDDDDD_NSEW,
+    DD_MMPMMM_NSEW,
+    DD_MM_SSPS_NSEW,
+    NSEW_DDPDDDDD,
+    NSEW_DD_MMPMMM,
+    NSEW_DD_MM_SSPS,
+    DEG_FORMAT_ENUM_COUNT
+} DegFormat;
+
+typedef enum
+{
+    SPEED_LOCATION_BOTTOM_LEFT,
+    SPEED_LOCATION_BOTTOM_RIGHT,
+    SPEED_LOCATION_TOP_RIGHT,
+    SPEED_LOCATION_TOP_LEFT,
+    SPEED_LOCATION_ENUM_COUNT
+} SpeedLocation;
+
+typedef enum
+{
+    MAP_UPDATE_ADD,
+    MAP_UPDATE_OVERWRITE,
+    MAP_UPDATE_AUTO,
+    MAP_UPDATE_DELETE,
+    MAP_UPDATE_ENUM_COUNT
+} MapUpdateType;
+
+typedef enum
+{
+    GPS_RCVR_NONE,
+    GPS_RCVR_BT,
+    GPS_RCVR_GPSD,
+    GPS_RCVR_FILE,
+    GPS_RCVR_ENUM_COUNT
+} GpsRcvrType;
+
+/** A general definition of a point in the Maemo Mapper unit system. */
+typedef struct _Point Point;
+struct _Point {
+    gint unitx;
+    gint unity;
+    time_t time;
+    gint altitude;
+};
+
+/** A WayPoint, which is a Point with a description. */
+typedef struct _WayPoint WayPoint;
+struct _WayPoint {
+    Point *point;
+    gchar *desc;
+};
+
+/** A Path is a set of PathPoints and WayPoints. */
+typedef struct _Path Path;
+struct _Path {
+    Point *head; /* points to first element in array; NULL if empty. */
+    Point *tail; /* points to last element in array. */
+    Point *cap; /* points after last slot in array. */
+    WayPoint *whead; /* points to first element in array; NULL if empty. */
+    WayPoint *wtail; /* points to last element in array. */
+    WayPoint *wcap; /* points after last slot in array. */
+};
+
+/** Data used during the SAX parsing operation. */
+typedef struct _SaxData SaxData;
+struct _SaxData {
+    SaxState state;
+    SaxState prev_state;
+    gint unknown_depth;
+    gboolean at_least_one_trkpt;
+    GString *chars;
+};
+
+typedef struct _PathSaxData PathSaxData;
+struct _PathSaxData {
+    SaxData sax_data;
+    Path path;
+};
+
+/** Data to describe a POI. */
+typedef struct _PoiInfo PoiInfo;
+struct _PoiInfo {
+    gint poi_id;
+    gint cat_id;
+    gfloat lat;
+    gfloat lon;
+    gchar *label;
+    gchar *desc;
+    gchar *clabel;
+};
+
+typedef struct _PoiSaxData PoiSaxData;
+struct _PoiSaxData {
+    SaxData sax_data;
+    GList *poi_list;
+    PoiInfo *curr_poi;
+};
+
+/** Data used during action: add or edit category/poi **/
+typedef struct _DeletePOI DeletePOI;
+struct _DeletePOI {
+    GtkWidget *dialog;
+    gchar *txt_label;
+    gint id;
+};
+
+/** Data regarding a map repository. */
+typedef struct _RepoData RepoData;
+struct _RepoData {
+    gchar *name;
+    gchar *url;
+    gchar *db_filename;
+    gchar *db_dirname;
+    gint dl_zoom_steps;
+    gint view_zoom_steps;
+    gboolean double_size;
+    gboolean nextable;
+    RepoType type;
+#ifdef MAPDB_SQLITE
+    sqlite3 *db;
+    sqlite3_stmt *stmt_map_select;
+    sqlite3_stmt *stmt_map_exists;
+    sqlite3_stmt *stmt_map_update;
+    sqlite3_stmt *stmt_map_insert;
+    sqlite3_stmt *stmt_map_delete;
+    sqlite3_stmt *stmt_dup_select;
+    sqlite3_stmt *stmt_dup_exists;
+    sqlite3_stmt *stmt_dup_insert;
+    sqlite3_stmt *stmt_dup_increm;
+    sqlite3_stmt *stmt_dup_decrem;
+    sqlite3_stmt *stmt_dup_delete;
+    sqlite3_stmt *stmt_trans_begin;
+    sqlite3_stmt *stmt_trans_commit;
+    sqlite3_stmt *stmt_trans_rollback;
+#else
+    GDBM_FILE db;
+#endif
+    GtkWidget *menu_item;
+};
+
+/** GPS Data and Satellite **/
+typedef struct _GpsData GpsData;
+struct _GpsData {
+    gint fix;
+    gint fixquality;
+    gfloat lat;
+    gfloat lon;
+    gfloat speed;    /* in knots */
+    gfloat maxspeed;    /* in knots */
+    gfloat heading;
+    gfloat hdop;
+    gfloat pdop;
+    gfloat vdop;
+    gint satinview;
+    gint satinuse;
+    gint satforfix[12];
+};
+
+typedef struct _GpsSatelliteData GpsSatelliteData;
+struct _GpsSatelliteData {
+    gint prn;
+    gint elevation;
+    gint azimuth;
+    gint snr;
+};
+
+/** Data used for rendering the entire screen. */
+typedef struct _MapRenderTask MapRenderTask;
+struct _MapRenderTask
+{
+    RepoData *repo;
+    Point new_center;
+    gint old_offsetx;
+    gint old_offsety;
+    gint screen_width_pixels;
+    gint screen_height_pixels;
+    gint zoom;
+    gint rotate_angle;
+    gboolean smooth_pan;
+    GdkPixbuf *pixbuf;
+};
+
+/** Data used for rendering the entire screen. */
+typedef struct _MapOffsetArgs MapOffsetArgs;
+struct _MapOffsetArgs
+{
+    gfloat old_center_offset_devx;
+    gfloat old_center_offset_devy;
+    gfloat new_center_offset_devx;
+    gfloat new_center_offset_devy;
+    gint rotate_angle;
+    gfloat percent_complete;
+};
+
+typedef struct _ThreadLatch ThreadLatch;
+struct _ThreadLatch
+{
+    gboolean is_open;
+    gboolean is_done_adding_tasks;
+    gint num_tasks;
+    gint num_done;
+    GMutex *mutex;
+    GCond *cond;
+};
+
+/** Data used during the asynchronous progress update phase of automatic map
+ * downloading. */
+typedef struct _MapUpdateTask MapUpdateTask;
+struct _MapUpdateTask
+{
+    gint id;
+    gint batch_id;
+    gint priority;
+    gboolean pending;
+    RepoData *repo;
+    MapUpdateType update_type;
+    gint zoom;
+    gint tilex;
+    gint tiley;
+    ThreadLatch *refresh_latch;
+    GnomeVFSResult vfs_result;
+    GdkPixbuf *pixbuf;
+};
+
+/** Data used during the asynchronous automatic route downloading operation. */
+typedef struct _AutoRouteDownloadData AutoRouteDownloadData;
+struct _AutoRouteDownloadData {
+    gboolean enabled;
+    gboolean in_progress;
+    gchar *source_url;
+    gchar *dest;
+    gboolean avoid_highways;
+};
+
+/** Data to describe the GPS connection. */
+typedef struct _GpsRcvrInfo GpsRcvrInfo;
+struct _GpsRcvrInfo {
+    GpsRcvrType type;
+    gchar *bt_mac;
+    gchar *bt_file;
+    gchar *file_path;
+    gchar *gpsd_host;
+    gint gpsd_port;
+};
+
+typedef struct _BrowseInfo BrowseInfo;
+struct _BrowseInfo {
+    GtkWidget *dialog;
+    GtkWidget *txt;
+};
+
+#endif /* ifndef MAEMO_MAPPER_TYPES_H */
diff --git a/src/util.c b/src/util.c
new file mode 100644 (file)
index 0000000..929125b
--- /dev/null
@@ -0,0 +1,528 @@
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#define _GNU_SOURCE
+
+#include <ctype.h>
+#include <string.h>
+#include <math.h>
+#include <hildon-widgets/hildon-note.h>
+
+#include "types.h"
+#include "data.h"
+#include "defines.h"
+
+#include "gpx.h"
+#include "util.h"
+
+
+/**
+ * Pop up a modal dialog box with simple error information in it.
+ */
+void
+popup_error(GtkWidget *window, const gchar *error)
+{
+    GtkWidget *dialog;
+    printf("%s(\"%s\")\n", __PRETTY_FUNCTION__, error);
+
+    dialog = hildon_note_new_information(GTK_WINDOW(window), error);
+
+    gtk_dialog_run(GTK_DIALOG(dialog));
+    gtk_widget_destroy(dialog);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+void
+deg_format(gfloat coor, gchar *scoor, gchar neg_char, gchar pos_char)
+{
+    gfloat min;
+    gfloat acoor = fabs(coor);
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    switch(_degformat)
+    {
+        case DDPDDDDD:
+            sprintf(scoor, "%.5f°", coor);
+            break;
+        case DDPDDDDD_NSEW:
+            sprintf(scoor, "%.5f° %c", acoor,
+                    coor < 0.f ? neg_char : pos_char);
+            break;
+        case NSEW_DDPDDDDD:
+            sprintf(scoor, "%c %.5f°",
+                    coor < 0.f ? neg_char : pos_char,
+                    acoor);
+            break;
+
+        case DD_MMPMMM:
+            sprintf(scoor, "%d°%06.3f'",
+                    (int)coor, (acoor - (int)acoor)*60.0);
+            break;
+        case DD_MMPMMM_NSEW:
+            sprintf(scoor, "%d°%06.3f' %c",
+                    (int)acoor, (acoor - (int)acoor)*60.0,
+                    coor < 0.f ? neg_char : pos_char);
+            break;
+        case NSEW_DD_MMPMMM:
+            sprintf(scoor, "%c %d° %06.3f'",
+                    coor < 0.f ? neg_char : pos_char,
+                    (int)acoor, (acoor - (int)acoor)*60.0);
+            break;
+
+        case DD_MM_SSPS:
+            min = (acoor - (int)acoor)*60.0;
+            sprintf(scoor, "%d°%02d'%04.1f\"", (int)coor, (int)min,
+                    ((min - (int)min)*60.0));
+            break;
+        case DD_MM_SSPS_NSEW:
+            min = (acoor - (int)acoor)*60.0;
+            sprintf(scoor, "%d°%02d'%04.1f\" %c", (int)acoor, (int)min,
+                    ((min - (int)min)*60.0),
+                    coor < 0.f ? neg_char : pos_char);
+            break;
+        case NSEW_DD_MM_SSPS:
+            min = (acoor - (int)acoor)*60.0;
+            sprintf(scoor, "%c %d° %02d' %04.1f\"",
+                    coor < 0.f ? neg_char : pos_char,
+                    (int)acoor, (int)min,
+                    ((min - (int)min)*60.0));
+            break;
+    }
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+/** Return the location (in units) of the given string address.  This function
+  * makes a call to the internet, so it may take some time. */
+Point locate_address(GtkWidget *parent, const gchar *addr)
+{
+    Path temp;
+    Point retval = _point_null;
+    GnomeVFSResult vfs_result;
+    gint size;
+    gchar *bytes = NULL;
+    gchar *addr_escaped;
+    gchar *buffer;
+    printf("%s(%s)\n", __PRETTY_FUNCTION__, addr);
+
+    addr_escaped = gnome_vfs_escape_string(addr);
+    buffer = g_strdup_printf(_route_dl_url, addr_escaped, addr_escaped);
+    g_free(addr_escaped);
+
+    /* Attempt to download the route from the server. */
+    if(GNOME_VFS_OK != (vfs_result = gnome_vfs_read_entire_file(
+                buffer, &size, &bytes)))
+    {
+        g_free(buffer);
+        g_free(bytes);
+        popup_error(parent, _("Failed to connect to GPX Directions server"));
+        return _point_null;
+    }
+
+    g_free(buffer);
+
+    MACRO_PATH_INIT(temp);
+
+    if(strncmp(bytes, "<?xml", strlen("<?xml")))
+    {
+        /* Not an XML document - must be bad locations. */
+        popup_error(parent, _("Invalid address."));
+    }
+    /* Else, if GPS is enabled, replace the route, otherwise append it. */
+    else if(!gpx_path_parse(&temp, bytes, size, 0) || !temp.head[1].unity)
+    {
+        popup_error(parent, _("Unknown error while locating address."));
+    }
+    else
+    {
+        /* Save Destination in Route Locations list. */
+        GtkTreeIter iter;
+        if(!g_slist_find_custom(_loc_list, addr, (GCompareFunc)strcmp))
+        {
+            _loc_list = g_slist_prepend(_loc_list, g_strdup(addr));
+            gtk_list_store_insert_with_values(_loc_model, &iter,
+                    INT_MAX, 0, addr, -1);
+        }
+
+        retval = temp.head[1];
+    }
+
+    MACRO_PATH_FREE(temp);
+    g_free(bytes);
+
+    vprintf("%s(): return (%d, %d)\n", __PRETTY_FUNCTION__,
+            retval.unitx, retval.unity);
+    return retval;
+}
+
+/**
+ * Calculate the distance between two lat/lon pairs.  The distance is returned
+ * in kilometers and should be converted using UNITS_CONVERT[_units].
+ */
+gfloat
+calculate_distance(gfloat lat1, gfloat lon1, gfloat lat2, gfloat lon2)
+{
+    gfloat dlat, dlon, slat, slon, a;
+
+    /* Convert to radians. */
+    lat1 = deg2rad(lat1);
+    lon1 = deg2rad(lon1);
+    lat2 = deg2rad(lat2);
+    lon2 = deg2rad(lon2);
+
+    dlat = lat2 - lat1;
+    dlon = lon2 - lon1;
+
+    slat = sinf(dlat / 2.f);
+    slon = sinf(dlon / 2.f);
+    a = (slat * slat) + (cosf(lat1) * cosf(lat2) * slon * slon);
+
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+    return ((2.f * atan2f(sqrtf(a), sqrtf(1.f - a))) * EARTH_RADIUS);
+}
+
+/**
+ * Calculate the bearing between two lat/lon pairs.  The bearing is returned
+ * as the angle from lat1/lon1 to lat2/lon2.
+ */
+gfloat
+calculate_bearing(gfloat lat1, gfloat lon1, gfloat lat2, gfloat lon2)
+{
+    gfloat x, y;
+    gfloat dlon = deg2rad(lon2 - lon1);
+    lat1 = deg2rad(lat1);
+    lat2 = deg2rad(lat2);
+
+    y = sinf(dlon) * cosf(lat2);
+    x = (cosf(lat1) * sinf(lat2)) - (sinf(lat1) * cosf(lat2) * cosf(dlon));
+
+    dlon = rad2deg(atan2f(y, x));
+    if(dlon < 0.f)
+        dlon += 360.f;
+    return dlon;
+}
+
+
+
+void
+force_min_visible_bars(HildonControlbar *control_bar, gint num_bars)
+{
+    GValue val;
+    printf("%s()\n", __PRETTY_FUNCTION__);
+    memset(&val, 0, sizeof(val));
+    g_value_init(&val, G_TYPE_INT);
+    g_value_set_int(&val, num_bars);
+    g_object_set_property(G_OBJECT(control_bar), "minimum-visible-bars", &val);
+    vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+gboolean
+banner_reset()
+{
+    printf("%s()\n", __PRETTY_FUNCTION__);
+
+    /* Re-enable any banners that might have been up. */
+    {
+        if(_connect_banner)
+        {
+            gtk_widget_hide(_connect_banner);
+            gtk_widget_unrealize(_connect_banner);
+            gtk_widget_realize(_connect_banner);
+            gtk_widget_show(_connect_banner);
+        }
+
+        if(_fix_banner)
+        {
+            gtk_widget_hide(_fix_banner);
+            gtk_widget_unrealize(_fix_banner);
+            gtk_widget_realize(_fix_banner);
+            gtk_widget_show(_fix_banner);
+        }
+
+        if(_waypoint_banner)
+        {
+            gtk_widget_hide(_waypoint_banner);
+            gtk_widget_unrealize(_waypoint_banner);
+            gtk_widget_realize(_waypoint_banner);
+            gtk_widget_show(_waypoint_banner);
+        }
+
+        if(_download_banner)
+        {
+            gtk_widget_hide(_download_banner);
+            gtk_widget_unrealize(_download_banner);
+            gtk_widget_realize(_download_banner);
+            gtk_widget_show(_download_banner);
+        }
+
+        /*
+        ConnState old_state = _gps_state;
+        set_conn_state(RCVR_OFF);
+        set_conn_state(old_state);
+        */
+    }
+
+    vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+    return FALSE;
+}
+/*
+ * Get one numeric token off the string, fractional part separator
+ * is ',' or '.' and number may follow any token from sep.
+ * Return value found is in d.
+ *
+ * If utf8_deg is set then accept also Unicode degree symbol U+00B0
+ * encoded as UTF-8 octets 0xc2 0xb0.
+ *
+ * @returns
+ *    0 : on error.
+ *    1 : when nothing or just white space was seen.
+ *    2 : when fractional number was seen.
+ *    3 : when whole number was seen.
+ *  In case 0, endptr points to the beginning of the input string nptr,
+ *  d is undefined.
+ *
+ *  In case 1 endptr points past the whitespace, d is undefined.
+ *
+ *  In cases 2 and 3 the found number is stored in d and endptr points
+ *  to first char not part of the number.
+ *
+ */
+gint
+strdmstod_1(gdouble *d, gchar *nptr, gchar **endptr, gchar *sep, gint utf8_deg)
+{
+    guchar *p;
+    gint v_flag, f_flag;
+    gdouble v;
+
+    p = nptr;
+
+    while (*p && isspace(*p)) {
+        p++;
+    }
+
+    v_flag = 0;
+    f_flag = 0;
+
+    /* whole part */
+    v = 0.0;
+    while (*p && isdigit(*p)) {
+        v *= 10;
+        v += *p++ - '0';
+        v_flag = 1;
+    }
+
+    if (v_flag) {
+        if (*p && (*p == '.' || *p == ',')) {
+            gdouble f;
+            gint n;
+
+            p++;
+
+            /* fractional part */
+            f = 0.0;
+            n = 1;
+            while (*p && isdigit(*p)) {
+                f *= 10.0;
+                f += *p++ - '0';
+                n *= 10;
+            }
+
+            if (n > 1) {
+                f_flag = 1;
+                v += f/n;
+            }
+        }
+
+        /* allow for extra sep char at the end */
+        if (*p && strchr(sep, *p)) {
+            p++;
+        } else if (utf8_deg && *p == 0xc2 && *(p+1) == 0xb0) {
+            p += 2;
+        }
+
+        *d = v;
+        if (endptr) *endptr = p;
+        return f_flag ? 2 : 3;
+    }
+
+    if (endptr) *endptr = p;
+    return *p == 0;
+}
+
+gdouble
+strdmstod_2(gchar *nptr, gchar **endptr)
+{
+    gint ret;
+    guchar *p;
+    gdouble d, m, s;
+
+    p = nptr;
+
+    /* degrees */
+    ret = strdmstod_1(&d, p, endptr, "dD@", 1);
+    switch (ret) {
+        case 0: return 0.0;
+        case 1:
+                if (endptr) *endptr = (char *)nptr;
+                return 0.0;
+        case 2: return d;
+    }
+
+    /* minutes */
+    p = *endptr;
+    m = 0.0;
+    ret = strdmstod_1(&m, p, endptr, "mM'", 0);
+    switch (ret) {
+        case 0: return 0.0;
+        case 1: return d;
+        case 2: return d + m/60.0;
+    }
+
+    /* seconds */
+    p = *endptr;
+    ret = strdmstod_1(&s, p, endptr, "sS\"", 0);
+    switch (ret) {
+        case 0: return 0.0;
+        case 1: return d + m/60.0;
+        case 2:
+        case 3: return d + m/60.0 + s/3600.0;
+    }
+
+    /* can't be here */
+    return 0.0;
+}
+
+/*
+ * format: / \s* [+-NSWE]? \s* ( d | D \s+ m | D \s+ M \s+ s ) [NSWE]? /x
+ * where D := / \d+[@d°]? /ix
+ *       M := / \d+['m]? /ix
+ *       d := / D | \d+[,.]\d+[@d°]? /ix
+ *       m := / M | \d+[,.]\d+['m]? /ix
+ *       s := / S | \d+[,.]\d+["s]? /ix
+ *
+ *   and N or W are treated as positive, S or E are treated as negative,
+ *   they may occur only once.
+ */
+gdouble
+strdmstod(const gchar *nptr, gchar **endptr)
+{
+    gint s;
+    gchar *p, *end;
+    gchar *sign = 0;
+    gdouble d;
+
+    p = (char *)nptr;
+
+    while (*p && isspace(*p))
+        p++;
+
+    if (!*p) {
+        if (endptr) *endptr = (char *)nptr;
+        return 0.0;
+    }
+
+    if (strchr("NWSE-+", *p)) {
+        sign = p;
+        p++;
+    }
+
+    d = strdmstod_2(p, &end);
+    if (p == end && d == 0.0) {
+        if (endptr) *endptr = end;
+        return d;
+    }
+
+    p = end;
+    while (*p && isspace(*p))
+        p++;
+
+    s = 1;
+    if (sign == 0) {
+        if (*p && strchr("NWSE", *p)) {
+            if (*p == 'S' || *p == 'E') s = -1;
+            p++;
+        }
+    } else {
+        if (*sign == 'S' || *sign == 'E' || *sign == '-') s = -1;
+    }
+
+    if (endptr) *endptr = p;
+    return s * d;
+}
+
+#if 0
+struct t_case {
+    gchar *fmt;
+    gdouble value;
+} t_cases[] = {
+    { "12°", 12 },
+    { "+12d", 12 },
+    { "-12.345d", -12.345 },
+    { "12.345 E", -12.345 },
+    { "12d34m", 12.5666667 },
+    { "N 12 34", 12.5666667 },
+    { "S 12d34.56m", -12.576 },
+    { "W 12 34.56", 12.576 },
+    { "E 12d34m56s", -12.582222 },
+    { "12 34 56 S", -12.582222 },
+    { "12 34 56", 12.582222 },
+    { "12d34m56.7s E", -12.582417 },
+    { "12 34 56.7 W", 12.582417 },
+    { "12° 34 56.7 W", 12.582417 },
+
+    { 0, 0 }
+};
+
+int
+strdmstod_test()
+{
+    struct t_case *t;
+    gint fail, ok;
+
+    fail = ok = 0;
+
+    for (t = t_cases; t->fmt; t++) {
+        gdouble v;
+        gchar *endp;
+
+        v = strdmstod(t->fmt, &endp);
+        if (endp == t->fmt || *endp != 0) {
+            fprintf(stderr, "FAIL syntax %s\n", t->fmt);
+            fail++;
+        } else if (fabs(v - t->value) > 0.000001) {
+            fprintf(stderr, "FAIL value %s -> %.10g (%.10g)\n",
+                    t->fmt, v, t->value);
+            fail++;
+        } else {
+            ok++;
+        }
+    }
+
+    if (fail == 0) {
+        fprintf(stderr, "ALL TESTS OK\n");
+    } else {
+        fprintf(stderr, "FAIL %d, OK %d\n", fail, ok);
+    }
+}
+#endif
diff --git a/src/util.h b/src/util.h
new file mode 100644 (file)
index 0000000..f223713
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2006, 2007 John Costigan.
+ *
+ * POI and GPS-Info code originally written by Cezary Jackiewicz.
+ *
+ * Default map data provided by http://www.openstreetmap.org/
+ *
+ * This file is part of Maemo Mapper.
+ *
+ * Maemo Mapper is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maemo Mapper is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAEMO_MAPPER_UTIL_H
+#define MAEMO_MAPPER_UTIL_H
+
+#include <hildon-widgets/hildon-controlbar.h>
+
+void popup_error(GtkWidget *window, const gchar *error);
+
+Point locate_address(GtkWidget *parent, const gchar *address);
+
+gfloat calculate_distance(gfloat lat1, gfloat lon1, gfloat lat2, gfloat lon2);
+gfloat calculate_bearing(gfloat lat1, gfloat lon1, gfloat lat2, gfloat lon2);
+
+void force_min_visible_bars(HildonControlbar *control_bar, gint num_bars);
+
+gboolean banner_reset();
+
+void deg_format(gfloat coor, gchar *scoor, gchar neg_char, gchar pos_char);
+
+gint strdmstod_1(gdouble *d, gchar *nptr, gchar **endptr, gchar *sep,
+        gint utf8_deg);
+gdouble strdmstod_2(gchar *nptr, gchar **endptr);
+gdouble strdmstod(const gchar *nptr, gchar **endptr);
+
+#endif /* ifndef MAEMO_MAPPER_UTIL_H */