summaryrefslogtreecommitdiffstats
path: root/kimagemapeditor
diff options
context:
space:
mode:
Diffstat (limited to 'kimagemapeditor')
-rw-r--r--kimagemapeditor/AUTHORS1
-rw-r--r--kimagemapeditor/COPYING280
-rw-r--r--kimagemapeditor/ChangeLog105
-rw-r--r--kimagemapeditor/INSTALL167
-rw-r--r--kimagemapeditor/Makefile.am63
-rw-r--r--kimagemapeditor/NEWS13
-rw-r--r--kimagemapeditor/README12
-rw-r--r--kimagemapeditor/TODO5
-rw-r--r--kimagemapeditor/VERSION1
-rw-r--r--kimagemapeditor/areacreator.cpp44
-rw-r--r--kimagemapeditor/areacreator.h35
-rw-r--r--kimagemapeditor/arealistview.cpp67
-rw-r--r--kimagemapeditor/arealistview.h47
-rw-r--r--kimagemapeditor/configure.in.in6
-rw-r--r--kimagemapeditor/drawzone.cpp896
-rw-r--r--kimagemapeditor/drawzone.h122
-rw-r--r--kimagemapeditor/dummy.cpp0
-rw-r--r--kimagemapeditor/imagemap.cpp395
-rw-r--r--kimagemapeditor/imagemap.h77
-rw-r--r--kimagemapeditor/imageslistview.cpp157
-rw-r--r--kimagemapeditor/imageslistview.h111
-rw-r--r--kimagemapeditor/kimagemapeditor.cpp2819
-rw-r--r--kimagemapeditor/kimagemapeditor.desktop55
-rw-r--r--kimagemapeditor/kimagemapeditor.h460
-rw-r--r--kimagemapeditor/kimagemapeditorpart.desktop54
-rw-r--r--kimagemapeditor/kimagemapeditorpartui.rc150
-rw-r--r--kimagemapeditor/kimagemapeditorui.rc25
-rw-r--r--kimagemapeditor/kimearea.cpp1749
-rw-r--r--kimagemapeditor/kimearea.h392
-rw-r--r--kimagemapeditor/kimecommands.cpp384
-rw-r--r--kimagemapeditor/kimecommands.h198
-rw-r--r--kimagemapeditor/kimecommon.h52
-rw-r--r--kimagemapeditor/kimedialogs.cpp874
-rw-r--r--kimagemapeditor/kimedialogs.h207
-rw-r--r--kimagemapeditor/kimeshell.cpp296
-rw-r--r--kimagemapeditor/kimeshell.h81
-rw-r--r--kimagemapeditor/main.cpp91
-rw-r--r--kimagemapeditor/mapslistview.cpp174
-rw-r--r--kimagemapeditor/mapslistview.h126
-rw-r--r--kimagemapeditor/pics/Makefile.am8
-rw-r--r--kimagemapeditor/pics/addpointcursor.pngbin0 -> 328 bytes
-rw-r--r--kimagemapeditor/pics/freehandcursor.pngbin0 -> 301 bytes
-rw-r--r--kimagemapeditor/pics/hi16-app-kimagemapeditor.pngbin0 -> 774 bytes
-rw-r--r--kimagemapeditor/pics/hi22-action-addpoint.pngbin0 -> 628 bytes
-rw-r--r--kimagemapeditor/pics/hi22-action-arrow.pngbin0 -> 583 bytes
-rw-r--r--kimagemapeditor/pics/hi22-action-circle.pngbin0 -> 488 bytes
-rw-r--r--kimagemapeditor/pics/hi22-action-circle2.pngbin0 -> 492 bytes
-rw-r--r--kimagemapeditor/pics/hi22-action-freehand.pngbin0 -> 635 bytes
-rw-r--r--kimagemapeditor/pics/hi22-action-lower.pngbin0 -> 361 bytes
-rw-r--r--kimagemapeditor/pics/hi22-action-polygon.pngbin0 -> 432 bytes
-rw-r--r--kimagemapeditor/pics/hi22-action-raise.pngbin0 -> 366 bytes
-rw-r--r--kimagemapeditor/pics/hi22-action-rectangle.pngbin0 -> 436 bytes
-rw-r--r--kimagemapeditor/pics/hi22-action-removepoint.pngbin0 -> 588 bytes
-rw-r--r--kimagemapeditor/pics/hi32-app-kimagemapeditor.pngbin0 -> 2706 bytes
-rw-r--r--kimagemapeditor/pics/hi48-app-kimagemapeditor.pngbin0 -> 4504 bytes
-rw-r--r--kimagemapeditor/pics/lo16-app-kimagemapeditor.pngbin0 -> 377 bytes
-rw-r--r--kimagemapeditor/pics/lo32-app-kimagemapeditor.pngbin0 -> 576 bytes
-rw-r--r--kimagemapeditor/pics/polygoncursor.pngbin0 -> 271 bytes
-rw-r--r--kimagemapeditor/pics/removepointcursor.pngbin0 -> 315 bytes
-rw-r--r--kimagemapeditor/qextfileinfo.cpp347
-rw-r--r--kimagemapeditor/qextfileinfo.h75
61 files changed, 11221 insertions, 0 deletions
diff --git a/kimagemapeditor/AUTHORS b/kimagemapeditor/AUTHORS
new file mode 100644
index 00000000..7aee7c48
--- /dev/null
+++ b/kimagemapeditor/AUTHORS
@@ -0,0 +1 @@
+Jan Schäfer <janschaefer@users.sourceforge.net>
diff --git a/kimagemapeditor/COPYING b/kimagemapeditor/COPYING
new file mode 100644
index 00000000..c7aea189
--- /dev/null
+++ b/kimagemapeditor/COPYING
@@ -0,0 +1,280 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ 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 Library General Public License instead.) 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.
+
+ 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.
+
+ 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.
+
+ 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
+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
+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
+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
diff --git a/kimagemapeditor/ChangeLog b/kimagemapeditor/ChangeLog
new file mode 100644
index 00000000..55983873
--- /dev/null
+++ b/kimagemapeditor/ChangeLog
@@ -0,0 +1,105 @@
+1.0 :
+- New features :
+ * French translation - Thanks to Germain Chazot
+ - KImageMapEditor is now translated to 4 languages :
+ German, spanish, french and dutch
+ * Improved session management
+ * Made it possible to start with the last opened document
+ * The ImageMapChoosDialog is only shown, if there are more then one map to choose.
+- Bug fixes :
+ * Fixed the bug that prevents from dropping html or image files
+ * Fixed another Mandrake compilation problem
+ * The area preview image size can now be changed by the properties dialog
+ * The highlight and show alt tag settings are now saved when used within Quanta.
+ * Completed spanish translation - Thanks to Antonio Crevillén
+
+1.0b3 :
+- New features :
+ * Added dutch translation - Thanks to Fabrice Mous
+- Bug fixes :
+ * added namespace to cout : std::cout to solve the compilation problem under Mandrake
+ * saveAs works now
+ * made the KPart readwrite only to work within Quanta correctly
+
+1.0b2 :
+- Bug fixes :
+ * Opening of an image over the toolbar or the menu entry file->open add
+ the image now correctly to the image list.
+ * The command line option --stdout works again.
+
+1.0b :
+- Note : Because of various internal modifications, this is intended to be a beta
+ release. So it's possible that KImageMapEditor may crash and/or
+ the content of the currently editing html file could be corrupted
+ or be lost at all.
+ KImageMapEditor therefore creates a backup file everytime you
+ save an html file. It ends with a ~.
+ Please only delete this file if you are sure that the original file
+ isn't corrupted.
+- New features :
+ * Converted the program to the KPart architecture, it can now be used as a
+ imagemap viewer plugin in Konqueror or as an edit plugin in Quanta.
+ * It's now possible to really edit a html file instead of creating always
+ a new one with only one imagemap.
+ * Added a listview of all imagemaps of the current editing html files.
+ It's now possible to switch between the different maps, to delete maps and
+ to add new maps to the html file.
+ * Added a listview of all images that are contained in the current html file.
+ It's now possible to switch between these images.
+ * Spanish translation - Thanks to Antonio Crevillén
+- Bug fixes :
+ * When KImageMapEditor was not properly installed with make install and
+ the required image files couldn't be found, KImageMapEditor now shows
+ an error message and exit(1), instead of crashing.
+
+0.9.5 :
+- New features :
+ * Tool for adding and removing points to/from a polygon with the mouse
+ * Freehand tool for drawing polygons
+ * German translation
+ * More zoom modes
+- Bug fixes :
+ * Some undo bugs which results in a crash -> fixed
+ * When switching from non-highlight mode to highlight mode the areas
+ weren't highlighted correctly -> fixed
+ * Crash when moving an area outside the drawing zone -> fixed
+
+0.9.4 :
+- New features :
+ * Areas can be highlighted
+ * Alt. text can be shown
+ * PHP-files can be read
+ * Property dialog extended
+ * New action : close file
+
+0.9.3 :
+- New features :
+ * Multiselection
+ * Keyboard can be used better
+ * New mouse cursors
+ * New Action : delete
+ * other new Actions
+
+0.9.2 :
+- New features :
+ * Undo / Redo for almost all actions
+ * Middle mouse click opens the properties dialog
+ * Possiblity of enable / disable the default area
+
+- Bug fixes :
+ * It's now possible to save to a file without an *.html,*.htm extension
+ * Creating a rectangle with a negative size ( and a following crash ) is no longer possible.
+
+0.9.1 :
+- New features :
+ * Better way of editing the area coordinates manually
+ - Possibility of adding and removing points to a polygon
+ * Cursor shape changes to indicate moving or resizing
+ * Circle drawing is now perfekt
+ * Possibility of changing the order of the areas
+
+- Bug fixes :
+ * When saving to an HTML file the ending </html> tag is no longer missing.
+ * When adding an area and pressing cancel the area will not be added.
+ * Restoring the window size works now
+
diff --git a/kimagemapeditor/INSTALL b/kimagemapeditor/INSTALL
new file mode 100644
index 00000000..02a4a074
--- /dev/null
+++ b/kimagemapeditor/INSTALL
@@ -0,0 +1,167 @@
+Basic Installation
+==================
+
+ These are generic installation instructions.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, a file
+`config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+ The file `configure.in' is used to create `configure' by a program
+called `autoconf'. You only need `configure.in' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system. If you're
+ using `csh' on an old version of System V, you might need to type
+ `sh ./configure' instead to prevent `csh' from trying to execute
+ `configure' itself.
+
+ Running `configure' takes a while. While running, it prints some
+ messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 4. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'.
+
+Compilers and Options
+=====================
+
+ Some systems require unusual options for compilation or linking that
+the `configure' script does not know about. You can give `configure'
+initial values for variables by setting them in the environment. Using
+a Bourne-compatible shell, you can do that on the command line like
+this:
+ CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+
+Or on systems that have the `env' program, you can do it like this:
+ env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+
+Compiling For Multiple Architectures
+====================================
+
+ You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+ If you have to use a `make' that does not supports the `VPATH'
+variable, you have to compile the package for one architecture at a time
+in the source code directory. After you have installed the package for
+one architecture, use `make distclean' before reconfiguring for another
+architecture.
+
+Installation Names
+==================
+
+ By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc. You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+ Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+ There may be some features `configure' can not figure out
+automatically, but needs to determine by the type of host the package
+will run on. Usually `configure' can figure that out, but if it prints
+a message saying it can not guess the host type, give it the
+`--host=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name with three fields:
+ CPU-COMPANY-SYSTEM
+
+See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the host type.
+
+ If you are building compiler tools for cross-compiling, you can also
+use the `--target=TYPE' option to select the type of system they will
+produce code for and the `--build=TYPE' option to select the type of
+system on which you are compiling the package.
+
+Sharing Defaults
+================
+
+ If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Operation Controls
+==================
+
+ `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+ Use and save the results of the tests in FILE instead of
+ `./config.cache'. Set FILE to `/dev/null' to disable caching, for
+ debugging `configure'.
+
+`--help'
+ Print a summary of the options to `configure', and exit.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made.
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`--version'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`configure' also accepts some other, not widely useful, options.
+
diff --git a/kimagemapeditor/Makefile.am b/kimagemapeditor/Makefile.am
new file mode 100644
index 00000000..3f2ed486
--- /dev/null
+++ b/kimagemapeditor/Makefile.am
@@ -0,0 +1,63 @@
+SUBDIRS = pics
+
+bin_PROGRAMS = kimagemapeditor
+kde_module_LTLIBRARIES = libkimagemapeditor.la
+
+METASOURCES = AUTO
+
+noinst_LTLIBRARIES = libkimagemapeditorcommon.la
+
+libkimagemapeditorcommon_la_SOURCES = \
+ qextfileinfo.cpp \
+ areacreator.cpp \
+ kimearea.cpp \
+ kimecommands.cpp \
+ kimedialogs.cpp \
+ kimagemapeditor.cpp \
+ drawzone.cpp \
+ arealistview.cpp \
+ imageslistview.cpp \
+ mapslistview.cpp
+
+libkimagemapeditor_la_SOURCES = \
+ dummy.cpp
+
+kimagemapeditor_SOURCES = \
+ main.cpp \
+ kimeshell.cpp
+
+
+noinst_HEADERS = \
+ qextfileinfo.h \
+ areacreator.h \
+ kimearea.h \
+ kimecommands.h \
+ kimedialogs.h \
+ kimagemapeditor.h \
+ drawzone.h \
+ kimeshell.h
+
+
+libkimagemapeditor_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries)
+libkimagemapeditor_la_LIBADD = libkimagemapeditorcommon.la $(LIB_KFILE) $(LIB_KPARTS) $(LIB_KHTML)
+
+kimagemapeditor_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+kimagemapeditor_LDADD = libkimagemapeditorcommon.la $(LIB_KFILE) $(LIB_KPARTS) $(LIB_KHTML)
+
+# set the include path for X, qt and KDE
+INCLUDES= $(all_includes)
+
+xdg_apps_DATA = kimagemapeditor.desktop
+
+rcdir = $(kde_datadir)/kimagemapeditor
+rc_DATA = kimagemapeditorui.rc \
+ kimagemapeditorpartui.rc
+
+kde_services_DATA = kimagemapeditorpart.desktop
+
+messages: rc.cpp
+ LIST=`find . -name \*.h -o -name \*.hh -o -name \*.H -o -name \*.hxx -o -name \*.hpp -o -name \*.cpp -o -name \*.cc -o -name \*.cxx -o -name \*.ecpp -o -name \*.C`; \
+ if test -n "$$LIST"; then \
+ $(XGETTEXT) $$LIST -o $(podir)/kimagemapeditor.pot; \
+ fi
+
diff --git a/kimagemapeditor/NEWS b/kimagemapeditor/NEWS
new file mode 100644
index 00000000..3957e33d
--- /dev/null
+++ b/kimagemapeditor/NEWS
@@ -0,0 +1,13 @@
+1.0 :
+- New features :
+ * French translation - Thanks to Germain Chazot
+ - KImageMapEditor is now translated to 4 languages :
+ German, spanish, french and dutch
+ * Session management
+ * Made it possible to start with the last opened document
+- Bug fixes :
+ * Fixed the bug that prevents from dropping html or image files
+ * Fixed another Mandrake compilation problem
+ * The area preview image size can now be changed by the properties dialog
+ * The highlight and show alt tag settings are now saved when used within Quanta.
+ * Completed spanish translation - Thanks to Antonio Crevillén
diff --git a/kimagemapeditor/README b/kimagemapeditor/README
new file mode 100644
index 00000000..b04c6794
--- /dev/null
+++ b/kimagemapeditor/README
@@ -0,0 +1,12 @@
+
+ ---------------------------------
+
+ KImageMapEditor
+
+ An HTML image map editor
+
+ Jan Schäfer
+
+ janschaefer@users.sourceforge.net
+
+ ---------------------------------
diff --git a/kimagemapeditor/TODO b/kimagemapeditor/TODO
new file mode 100644
index 00000000..c629ca1d
--- /dev/null
+++ b/kimagemapeditor/TODO
@@ -0,0 +1,5 @@
+- Create a handbook
+- Add Tip Of The Day
+- Translate to more languages ( help would be really appreciated )
+- Have fun with it ;-)
+
diff --git a/kimagemapeditor/VERSION b/kimagemapeditor/VERSION
new file mode 100644
index 00000000..51164aba
--- /dev/null
+++ b/kimagemapeditor/VERSION
@@ -0,0 +1 @@
+KImageMapEditor v1.0.1
diff --git a/kimagemapeditor/areacreator.cpp b/kimagemapeditor/areacreator.cpp
new file mode 100644
index 00000000..739409fc
--- /dev/null
+++ b/kimagemapeditor/areacreator.cpp
@@ -0,0 +1,44 @@
+/***************************************************************************
+ areacreator.cpp - description
+ -------------------
+ begin : Wed Apr 3 2002
+ copyright : (C) 2002 by Jan Schäfer
+ email : janschaefer@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "areacreator.h"
+
+
+
+Area* AreaCreator::create( Area::ShapeType type)
+{
+ switch ( type ) {
+ case Area::Rectangle : return new RectArea();
+ case Area::Circle : return new CircleArea();
+ case Area::Polygon : return new PolyArea();
+ case Area::Default : return new DefaultArea();
+ case Area::Selection : return new AreaSelection();
+ default : return new Area();
+ }
+}
+
+
+Area* AreaCreator::create( KImageMapEditor::ToolType type)
+{
+ switch ( type ) {
+ case KImageMapEditor::Rectangle : return new RectArea();
+ case KImageMapEditor::Circle : return new CircleArea();
+ case KImageMapEditor::Polygon : return new PolyArea();
+ case KImageMapEditor::Freehand : return new PolyArea();
+ default : return new Area();
+ }
+}
diff --git a/kimagemapeditor/areacreator.h b/kimagemapeditor/areacreator.h
new file mode 100644
index 00000000..c232d4f3
--- /dev/null
+++ b/kimagemapeditor/areacreator.h
@@ -0,0 +1,35 @@
+/***************************************************************************
+ areacreator.h - description
+ -------------------
+ begin : Wed Apr 3 2002
+ copyright : (C) 2002 by Jan Schäfer
+ email : janschaefer@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef AREACREATOR_H
+#define AREACREATOR_H
+
+
+#include "kimagemapeditor.h"
+
+/**
+ * A small creator class which follows the
+ * factory method pattern
+ */
+class AreaCreator
+{
+ public :
+ static Area* create( Area::ShapeType );
+ static Area* create( KImageMapEditor::ToolType);
+};
+
+#endif
diff --git a/kimagemapeditor/arealistview.cpp b/kimagemapeditor/arealistview.cpp
new file mode 100644
index 00000000..80cd3265
--- /dev/null
+++ b/kimagemapeditor/arealistview.cpp
@@ -0,0 +1,67 @@
+/***************************************************************************
+ arealistview.cpp - description
+ -------------------
+ begin : Weg Feb 26 2003
+ copyright : (C) 2003 by Jan Schäfer
+ email : janschaefer@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+// QT
+#include <klistview.h>
+#include <qpushbutton.h>
+#include <qhbox.h>
+#include <qwhatsthis.h>
+#include <qtooltip.h>
+
+// KDE
+#include <kiconloader.h>
+#include <klocale.h>
+
+// local
+#include "kimearea.h"
+#include "arealistview.h"
+
+
+AreaListView::AreaListView(QWidget *parent, const char *name)
+ : QVBox(parent, name)
+{
+ listView = new KListView(this);
+ listView->addColumn(i18n("Areas"));
+ listView->addColumn(i18n("Preview"));
+
+ listView->setMultiSelection(true);
+ listView->setSelectionMode( QListView::Extended );
+ listView->setSorting(-1); // The user can't sort by clicking on the header
+ listView->setFullWidth(true);
+
+
+ QWhatsThis::add( listView, i18n("<h3>Area List</h3>The area list shows you all areas of the map.<br>"
+ "The left column shows the link associated with the area; the right "
+ "column shows the part of the image that is covered by the area.<br>"
+ "The maximum size of the preview images can be configured."));
+ QToolTip::add( listView, i18n("A list of all areas"));
+
+ QHBox *hbox= new QHBox(this);
+ upBtn= new QPushButton("",hbox);
+ upBtn->setIconSet(SmallIconSet("up"));
+
+ downBtn= new QPushButton("",hbox);
+ downBtn->setIconSet(SmallIconSet("down"));
+
+}
+
+
+AreaListView::~AreaListView()
+{
+}
+
+#include "arealistview.moc"
diff --git a/kimagemapeditor/arealistview.h b/kimagemapeditor/arealistview.h
new file mode 100644
index 00000000..6037f5ee
--- /dev/null
+++ b/kimagemapeditor/arealistview.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+ arealistview.h - description
+ -------------------
+ begin : Weg Feb 26 2003
+ copyright : (C) 2003 by Jan Schäfer
+ email : janschaefer@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef _AREALISTVIEW_H_
+#define _AREALISTVIEW_H_
+
+#include <qwidget.h>
+#include <qvbox.h>
+
+class KListView;
+class QPushButton;
+class Area;
+
+/**
+ * This class consists of a ListView and two arrow buttons on the bottom.
+ * It shows all Areas of the current map.
+ * Jan Schaefer
+ **/
+class AreaListView : public QVBox
+{
+ Q_OBJECT
+
+public:
+ AreaListView(QWidget *parent, const char *name);
+ ~AreaListView();
+
+ KListView* listView;
+ QPushButton *upBtn;
+ QPushButton *downBtn;
+
+};
+
+#endif
diff --git a/kimagemapeditor/configure.in.in b/kimagemapeditor/configure.in.in
new file mode 100644
index 00000000..f9c208de
--- /dev/null
+++ b/kimagemapeditor/configure.in.in
@@ -0,0 +1,6 @@
+#MIN_CONFIG
+
+AM_INIT_AUTOMAKE(kimagemapeditor, 1.0)
+AC_C_BIGENDIAN
+AC_CHECK_KDEMAXPATHLEN
+
diff --git a/kimagemapeditor/drawzone.cpp b/kimagemapeditor/drawzone.cpp
new file mode 100644
index 00000000..a5bf5612
--- /dev/null
+++ b/kimagemapeditor/drawzone.cpp
@@ -0,0 +1,896 @@
+/***************************************************************************
+ drawzone.cpp - description
+ -------------------
+ begin : Wed Apr 4 2001
+ copyright : (C) 2001 by Jan Sch�er
+ email : j_schaef@informatik.uni-kl.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+// QT
+#include <qbitmap.h>
+#include <qpainter.h>
+#include <qdragobject.h>
+#include <qpixmap.h>
+
+// KDE
+#include <kdebug.h>
+#include <kurldrag.h>
+#include <kglobal.h>
+#include <kstandarddirs.h>
+#include <kapplication.h>
+#include <kmimetype.h>
+
+// Local
+#include "drawzone.h"
+#include "kimagemapeditor.h"
+#include "kimecommands.h"
+#include "areacreator.h"
+
+#include "kimecommon.h"
+
+DrawZone::DrawZone(QWidget *parent,KImageMapEditor* _imageMapEditor)
+ : QScrollView(parent)
+{
+ imageMapEditor=_imageMapEditor;
+// setPicture(QImage());
+ currentAction=None;
+ currentArea=0L;
+ oldArea=0L;
+ _zoom=1;
+ if (imageMapEditor->isReadWrite()) {
+ viewport()->setMouseTracking(true);
+ viewport()->setAcceptDrops(true);
+ this->setAcceptDrops(true);
+ }
+ else
+ viewport()->setMouseTracking(false);
+
+ setDragAutoScroll(true);
+
+ // The cross rectangle cursor
+ QBitmap b(32,32,true);
+ QBitmap b2(32,32,true);
+ QPainter p(&b);
+ // the cross
+ p.drawLine(0,8,6,8);
+ p.drawLine(10,8,16,8);
+ p.drawLine(8,0,8,6);
+ p.drawLine(8,10,8,16);
+ // the rectangle
+ p.drawRect(17,17,8,6);
+
+ p.end();
+
+ p.begin(&b2);
+ // the cross black lines
+ p.drawLine(0,8,6,8);
+ p.drawLine(10,8,16,8);
+ p.drawLine(8,0,8,6);
+ p.drawLine(8,10,8,16);
+
+ // the cross white lines
+ p.drawLine(0,7,6,7);
+ p.drawLine(10,7,16,7);
+ p.drawLine(7,0,7,6);
+ p.drawLine(7,10,7,16);
+
+ // the cross white lines
+ p.drawLine(0,9,6,9);
+ p.drawLine(10,9,16,9);
+ p.drawLine(9,0,9,6);
+ p.drawLine(9,10,9,16);
+
+ // the rectangles
+ p.drawRect(17,17,8,6); // black
+ p.drawRect(18,18,6,4); // white
+ p.drawRect(16,16,10,8); // white
+
+ p.end();
+
+ RectangleCursor = QCursor(b,b2,8,8);
+
+
+ // The cross circle cursor
+ b = QBitmap(32,32,true);
+ b2 = QBitmap(32,32,true);
+ p.begin(&b);
+ // the cross
+ p.drawLine(0,8,6,8);
+ p.drawLine(10,8,16,8);
+ p.drawLine(8,0,8,6);
+ p.drawLine(8,10,8,16);
+ // the circle
+ p.drawEllipse(17,17,8,8);
+
+ p.end();
+
+ p.begin(&b2);
+ // the cross black lines
+ p.drawLine(0,8,6,8);
+ p.drawLine(10,8,16,8);
+ p.drawLine(8,0,8,6);
+ p.drawLine(8,10,8,16);
+
+ // the cross white lines
+ p.drawLine(0,7,6,7);
+ p.drawLine(10,7,16,7);
+ p.drawLine(7,0,7,6);
+ p.drawLine(7,10,7,16);
+
+ // the cross white lines
+ p.drawLine(0,9,6,9);
+ p.drawLine(10,9,16,9);
+ p.drawLine(9,0,9,6);
+ p.drawLine(9,10,9,16);
+
+ // the circles
+ p.drawEllipse(17,17,8,8); // black
+ p.drawEllipse(16,16,10,10); // white
+ p.drawEllipse(18,18,6,6); // white
+
+ p.end();
+
+ CircleCursor = QCursor(b,b2,8,8);
+
+ QString path = KGlobal::dirs()->findResourceDir( "data", "kimagemapeditor/polygoncursor.png" ) + "kimagemapeditor/polygoncursor.png";
+ PolygonCursor = QCursor(QPixmap(path),8,8);
+
+ path = KGlobal::dirs()->findResourceDir( "data", "kimagemapeditor/freehandcursor.png" ) + "kimagemapeditor/freehandcursor.png";
+ FreehandCursor = QCursor(QPixmap(path),8,8);
+
+ path = KGlobal::dirs()->findResourceDir( "data", "kimagemapeditor/addpointcursor.png" ) + "kimagemapeditor/addpointcursor.png";
+ AddPointCursor = QCursor(QPixmap(path),8,8);
+
+ path = KGlobal::dirs()->findResourceDir( "data", "kimagemapeditor/removepointcursor.png" ) + "kimagemapeditor/removepointcursor.png";
+ RemovePointCursor = QCursor(QPixmap(path),8,8);
+}
+
+DrawZone::~DrawZone(){
+}
+
+void DrawZone::setPicture(const QImage &_image) {
+ image=_image;
+//- zoomedImage.convertFromImage(image);
+ setZoom(_zoom);
+}
+
+void DrawZone::setZoom(double z)
+{
+ _zoom=z;
+ imageRect.setHeight(myround(image.height()*_zoom));
+ imageRect.setWidth(myround(image.width()*_zoom));
+ zoomedImage=QPixmap(imageRect.width(),imageRect.height());
+ QPainter p(&zoomedImage);
+ p.scale(z,z);
+ QPixmap pix;
+ pix.convertFromImage(image);
+ // if the picture has transparent areas,
+ // fill them with Gimp like background
+ if (pix.mask()) {
+ QPixmap backPix(32,32);
+ QPainter p2(&backPix);
+ p2.fillRect(0,0,32,32,QColor(156,149,156));
+ p2.fillRect(0,16,16,16,QColor(98,105,98));
+ p2.fillRect(16,0,16,16,QColor(98,105,98));
+ p2.flush();
+ p.setPen(QPen());
+ p.fillRect(imageRect.left(),imageRect.top(),imageRect.width(),imageRect.height(),QBrush(QColor("black"),backPix));
+ }
+ p.drawPixmap(imageRect.left(),imageRect.top(),pix);
+ p.flush();
+ resizeContents(visibleWidth()>imageRect.width() ? visibleWidth() : imageRect.width(),
+ visibleHeight()>imageRect.height() ? visibleHeight() : imageRect.height());
+ repaintContents(0,0,contentsWidth(),contentsHeight(),true);
+}
+
+QPoint DrawZone::translateFromZoom(const QPoint & p) const {
+ return QPoint((int)(p.x()/_zoom),(int)(p.y()/_zoom));
+}
+
+QRect DrawZone::translateFromZoom(const QRect & p) const {
+ return QRect((int)(p.x()/_zoom),(int) (p.y()/_zoom),
+ (int)(p.width()/_zoom),(int)(p.height()/_zoom));
+}
+
+QPoint DrawZone::translateToZoom(const QPoint & p) const {
+ return QPoint(myround(p.x()*_zoom),myround(p.y()*_zoom));
+}
+
+QRect DrawZone::translateToZoom(const QRect & r) const {
+// return QRect(round(r.x()*_zoom),round(r.y()*_zoom),
+// round(r.width()*_zoom),round(r.height()*_zoom));
+ return QRect((int)(r.x()*_zoom),(int)(r.y()*_zoom),
+ (int)(r.width()*_zoom+2),(int)(r.height()*_zoom+2));
+}
+
+void DrawZone::contentsMouseDoubleClickEvent(QMouseEvent* e) {
+ if ( ! imageMapEditor->isReadWrite())
+ return;
+
+ QPoint point=e->pos();
+ point-=imageRect.topLeft();
+ point=translateFromZoom(point);
+ if ( currentAction==None &&
+ (currentArea=imageMapEditor->onArea(point)))
+ {
+ imageMapEditor->deselectAll();
+ imageMapEditor->select(currentArea);
+ currentArea=imageMapEditor->selected();
+ imageMapEditor->showTagEditor(imageMapEditor->selected());
+ }
+
+}
+
+void DrawZone::contentsMousePressEvent(QMouseEvent* e)
+{
+ if ( ! imageMapEditor->isReadWrite())
+ return;
+
+ drawStart=e->pos();
+ // Check if it's on picture if not
+ // move it to the picture's border
+ if (!imageRect.contains(drawStart)) {
+ if (drawStart.x()>imageRect.right())
+ drawStart.setX(imageRect.right());
+ if (drawStart.x()<imageRect.left())
+ drawStart.setX(imageRect.left());
+ if (drawStart.y()>imageRect.bottom())
+ drawStart.setY(imageRect.bottom());
+ if (drawStart.y()<imageRect.top())
+ drawStart.setY(imageRect.top());
+ }
+
+ // Translate it to picture coordinates
+ drawStart-=imageRect.topLeft();
+ QPoint zoomedPoint = drawStart;
+ drawStart=translateFromZoom(drawStart);
+ delete oldArea;
+ oldArea=0L;
+
+ if (currentArea)
+ {
+ oldArea=currentArea->clone();
+ }
+
+ if ( currentAction==None ) {
+ if (e->button()==RightButton)
+ {
+ if ( (currentArea=imageMapEditor->onArea(drawStart)) )
+ {
+ if ( ! currentArea->isSelected())
+ {
+ imageMapEditor->deselectAll();
+ imageMapEditor->select(currentArea);
+ }
+ currentArea=imageMapEditor->selected();
+ }
+
+ imageMapEditor->slotShowMainPopupMenu(e->globalPos());
+
+ }
+ else
+ if (e->button()==MidButton) {
+ contentsMouseDoubleClickEvent(e);
+ }
+ else // LeftClick on selectionpoint
+ if ((currentArea=imageMapEditor->selected()) &&
+ (currentSelectionPoint=currentArea->onSelectionPoint(zoomedPoint,_zoom)))
+ {
+ oldArea=currentArea->clone();
+
+ if ( (imageMapEditor->currentToolType() == KImageMapEditor::RemovePoint) &&
+ (imageMapEditor->selected()->selectionPoints()->count()>3) )
+ {
+ currentAction=RemovePoint;
+ }
+ else
+ {
+ currentAction=MoveSelectionPoint;
+ currentArea->setMoving(true);
+ }
+
+ } else // leftclick not on selectionpoint but on area
+ if ((currentArea=imageMapEditor->onArea(drawStart)))
+ {
+ if ( imageMapEditor->currentToolType() == KImageMapEditor::AddPoint )
+ {
+ currentAction=AddPoint;
+ viewport()->setCursor(AddPointCursor);
+ oldArea=currentArea->clone();
+ }
+ else
+ {
+ currentAction=MoveArea;
+ viewport()->setCursor(sizeAllCursor);
+
+ if ( currentArea->isSelected() ) {
+ if ( (e->state() & ControlButton) )
+ imageMapEditor->deselect(currentArea);
+ } else
+ {
+ if ( (e->state() & ControlButton) )
+ imageMapEditor->select( currentArea );
+ else {
+ imageMapEditor->deselectAll();
+ imageMapEditor->select( currentArea );
+ }
+ }
+
+ currentArea = imageMapEditor->selected();
+ currentArea->setMoving(true);
+
+ oldArea=currentArea->clone();
+ }
+ }
+ else // leftclick on the background
+ if ( (imageMapEditor->currentToolType()==KImageMapEditor::Rectangle) ||
+ (imageMapEditor->currentToolType()==KImageMapEditor::Circle) ||
+ (imageMapEditor->currentToolType()==KImageMapEditor::Polygon) ||
+ (imageMapEditor->currentToolType()==KImageMapEditor::Freehand))
+ {
+ currentArea=AreaCreator::create(imageMapEditor->currentToolType());
+
+ currentArea->setRect(QRect(drawStart,drawStart));
+ currentArea->setSelected(false);
+ imageMapEditor->deselectAll();
+
+ switch (imageMapEditor->currentToolType()) {
+ case KImageMapEditor::Rectangle : currentAction=DrawRectangle; break;
+ case KImageMapEditor::Circle : currentAction=DrawCircle; break;
+ case KImageMapEditor::Polygon :
+ currentAction=DrawPolygon;
+ currentArea->addCoord(drawStart);
+ currentSelectionPoint=currentArea->selectionPoints()->last();
+ break;
+ case KImageMapEditor::Freehand :
+ currentAction=DrawFreehand;
+ //currentArea->addCoord(drawStart);
+ currentArea->setFinished(false);
+ break;
+ default: break;
+ }
+ }
+ else
+ // leftclicked with the arrow at an areafree position
+ if (imageMapEditor->currentToolType()==KImageMapEditor::Selection)
+ {
+ currentArea=0L;
+ imageMapEditor->deselectAll();
+ // Start drawing a selection rectangle
+ currentAction=DoSelect;
+ oldSelectionRect = imageRect;
+ }
+ } else
+ if ( currentAction==DrawPolygon) {
+
+ }
+
+ QRect r;
+ if (oldArea)
+ r=oldArea->selectionRect();
+ if (currentArea) {
+ r= r | currentArea->selectionRect();
+ repaintContents(translateToZoom(r),false);
+ }
+
+
+}
+
+void DrawZone::contentsMouseReleaseEvent(QMouseEvent *e) {
+ if ( ! imageMapEditor->isReadWrite())
+ return;
+
+ QPoint drawEnd=e->pos();
+
+ // Check if it's on picture if not
+ // move it to the picture's border
+ if (!imageRect.contains(drawEnd)) {
+ if (drawEnd.x()>imageRect.right())
+ drawEnd.setX(imageRect.right());
+ if (drawEnd.x()<imageRect.left())
+ drawEnd.setX(imageRect.left());
+ if (drawEnd.y()>imageRect.bottom())
+ drawEnd.setY(imageRect.bottom());
+ if (drawEnd.y()<imageRect.top())
+ drawEnd.setY(imageRect.top());
+ }
+ // Translate it to picture coordinates
+ drawEnd-=imageRect.topLeft();
+ QPoint zoomedPoint=drawEnd;
+
+ drawEnd=translateFromZoom(drawEnd);
+
+ if (currentAction==DrawCircle || currentAction==DrawRectangle) {
+ currentAction=None;
+ imageMapEditor->commandHistory()->addCommand(
+ new CreateCommand( imageMapEditor, currentArea ), true);
+ } else
+ if (currentAction==DrawPolygon) {
+ // If the number of Polygonpoints is more than 2
+ // and clicked on the first PolygonPoint or
+ // the right Button was pressed the Polygon is finished
+ if ((currentArea->selectionPoints()->count()>2)
+ && (currentArea->selectionPoints()->first()->contains(drawEnd)
+ || (e->button()==RightButton)))
+ {
+ currentArea->setFinished(true);
+ currentAction=None;
+ imageMapEditor->commandHistory()->addCommand(
+ new CreateCommand( imageMapEditor, currentArea ), true);
+ } else
+ {
+ currentArea->insertCoord(currentArea->countSelectionPoints()-1, drawEnd);
+ currentSelectionPoint=currentArea->selectionPoints()->last();
+ }
+ } else
+ if (currentAction==DrawFreehand)
+ {
+ currentArea->setFinished(true);
+ currentArea->simplifyCoords();
+ currentAction=None;
+ imageMapEditor->commandHistory()->addCommand(
+ new CreateCommand( imageMapEditor, currentArea ), true);
+ } else
+ if (currentAction==MoveArea) {
+ QPoint p1 = oldArea->rect().topLeft();
+ QPoint p2 = imageMapEditor->selected()->rect().topLeft();
+
+ if (p1 != p2)
+ {
+ imageMapEditor->commandHistory()->addCommand(
+ new MoveCommand( imageMapEditor, imageMapEditor->selected(), oldArea->rect().topLeft()),true);
+ imageMapEditor->slotAreaChanged(currentArea);
+ } else
+ imageMapEditor->updateSelection();
+
+ currentAction=None;
+ } else
+ if (currentAction==MoveSelectionPoint) {
+ imageMapEditor->commandHistory()->addCommand(
+ new ResizeCommand( imageMapEditor, imageMapEditor->selected(), oldArea),true);
+ imageMapEditor->slotAreaChanged(currentArea);
+ currentAction=None;
+ } else
+ if (currentAction==RemovePoint) {
+ if (currentSelectionPoint==currentArea->onSelectionPoint(zoomedPoint,_zoom))
+ {
+ currentArea->removeSelectionPoint(currentSelectionPoint);
+
+ imageMapEditor->commandHistory()->addCommand(
+ new RemovePointCommand( imageMapEditor, imageMapEditor->selected(), oldArea),true);
+ imageMapEditor->slotAreaChanged(currentArea);
+ }
+ currentAction=None;
+ } else
+ if (currentAction==AddPoint)
+ {
+ if (currentArea==imageMapEditor->onArea(drawEnd))
+ {
+ imageMapEditor->commandHistory()->addCommand(
+ new AddPointCommand( imageMapEditor, imageMapEditor->selected(), drawEnd),true);
+ imageMapEditor->slotAreaChanged(currentArea);
+ }
+ currentAction=None;
+ } else
+ if (currentAction==DoSelect) {
+ currentAction=None;
+
+ QRect r(drawStart.x(),drawStart.y(),drawCurrent.x()-drawStart.x(),drawCurrent.y()-drawStart.y());
+ r = r.normalize();
+
+ AreaListIterator it=imageMapEditor->areaList();
+ for ( ; it.current() != 0L ; ++it ) {
+ if ( it.current()->rect().intersects(r) )
+ {
+ if (!it.current()->isSelected() )
+ imageMapEditor->selectWithoutUpdate( it.current() );
+ }
+ else
+ if (it.current()->isSelected())
+ imageMapEditor->deselectWithoutUpdate( it.current() );
+ }
+
+ imageMapEditor->updateActionAccess();
+ imageMapEditor->updateSelection();
+ repaintContents(imageRect,false);
+ } else {
+ currentAction=None;
+ }
+ imageMapEditor->slotChangeStatusCoords(drawEnd.x(),drawEnd.y());
+ if (currentArea)
+ {
+ currentArea->setMoving(false);
+ repaintArea(*currentArea);
+ }
+ delete oldArea;
+ oldArea=0L;
+// repaintContents(0,0,contentsWidth(),contentsHeight(),false);
+ imageMapEditor->slotUpdateSelectionCoords();
+}
+
+
+void DrawZone::contentsMouseMoveEvent(QMouseEvent *e)
+{
+ if ( ! imageMapEditor->isReadWrite())
+ return;
+
+
+ drawCurrent=e->pos();
+
+ // If outside the image
+ // set it to the border
+ if (!imageRect.contains(drawCurrent)) {
+ if (drawCurrent.x()>imageRect.right())
+ drawCurrent.setX(imageRect.right());
+ if (drawCurrent.x()<imageRect.left())
+ drawCurrent.setX(imageRect.left());
+ if (drawCurrent.y()>imageRect.bottom())
+ drawCurrent.setY(imageRect.bottom());
+ if (drawCurrent.y()<imageRect.top())
+ drawCurrent.setY(imageRect.top());
+ }
+
+ // Translate to image coordinates
+ drawCurrent-=imageRect.topLeft();
+ QPoint zoomedPoint=drawCurrent;
+ drawCurrent=translateFromZoom(drawCurrent);
+
+ if (currentAction==DrawRectangle) {
+ // To avoid flicker, only repaint the minimum rect
+ QRect oldRect=translateToZoom(currentArea->rect());
+ currentArea->setRect(QRect(drawStart,drawCurrent).normalize());
+ QRect newRect=translateToZoom(currentArea->selectionRect());
+ QRect r=oldRect | newRect;
+ repaintContents(r,false);
+ imageMapEditor->slotUpdateSelectionCoords( currentArea->rect() );
+ } else
+ if (currentAction==DrawCircle) {
+ QRect oldRect=translateToZoom(currentArea->rect());
+
+ // We don't want ellipses
+ int maxDistance=myabs(drawStart.x()-drawCurrent.x()) >
+ myabs(drawStart.y()-drawCurrent.y()) ?
+ myabs(drawStart.x()-drawCurrent.x()) :
+ myabs(drawStart.y()-drawCurrent.y()) ;
+
+ int xDiff=maxDistance;
+ int yDiff=maxDistance;
+
+ if ( drawStart.x()-drawCurrent.x() > 0)
+ xDiff=-xDiff;
+
+ if ( drawStart.y()-drawCurrent.y() > 0)
+ yDiff=-yDiff;
+
+ QPoint endPoint( drawStart.x()+xDiff, drawStart.y()+yDiff);
+
+ currentArea->setRect(QRect(drawStart,endPoint).normalize());
+ QRect newRect=translateToZoom(currentArea->rect());
+ QRect r=oldRect | newRect;
+ repaintContents(r,false);
+ imageMapEditor->slotUpdateSelectionCoords( currentArea->rect() );
+ } else
+ if ( currentAction==DrawPolygon ) {
+ QRect oldRect=translateToZoom(currentArea->rect());
+ currentArea->moveSelectionPoint(currentSelectionPoint,drawCurrent);
+ QRect newRect=translateToZoom(currentArea->rect());
+ QRect r=oldRect | newRect;
+ repaintContents(r,false);
+ } else
+ if ( currentAction==DrawFreehand) {
+ QRect oldRect=translateToZoom(currentArea->rect());
+ currentArea->insertCoord(currentArea->countSelectionPoints(), drawCurrent);
+ QRect newRect=translateToZoom(currentArea->rect());
+ QRect r=oldRect | newRect;
+ repaintContents(r,false);
+ } else
+ if ( currentAction==MoveArea ) {
+ QRect oldRect=translateToZoom(currentArea->selectionRect());
+ currentArea->moveBy((drawCurrent-drawStart).x(),(drawCurrent-drawStart).y());
+ QRect newRect=translateToZoom(currentArea->selectionRect());
+ QRect r=oldRect | newRect;
+ currentArea->setMoving(true);
+ repaintContents(r,false);
+ drawStart=drawCurrent;
+ imageMapEditor->slotUpdateSelectionCoords();
+ } else
+ if ( currentAction==MoveSelectionPoint ) {
+ QRect oldRect=translateToZoom(currentArea->selectionRect());
+ currentArea->moveSelectionPoint(currentSelectionPoint,drawCurrent);
+ QRect newRect=translateToZoom(currentArea->selectionRect());
+ QRect r=oldRect | newRect;
+ repaintContents(r,false);
+ imageMapEditor->slotUpdateSelectionCoords();
+ } else
+ if (currentAction==DoSelect) {
+
+ QRect r(drawStart.x(),drawStart.y(),drawCurrent.x()-drawStart.x(),drawCurrent.y()-drawStart.y());
+ r = r.normalize();
+// r = translateFromZoom(r);
+/*
+ AreaListIterator it=imageMapEditor->areaList();
+ for ( ; it.current() != 0L ; ++it ) {
+ if ( it.current()->rect().intersects(r) )
+ {
+ if (!it.current()->isSelected() )
+ imageMapEditor->selectWithoutUpdate( it.current() );
+ }
+ else
+ if (it.current()->isSelected())
+ imageMapEditor->deselectWithoutUpdate( it.current() );
+ }
+*/
+ // We don't have to repaint the hole selection rectangle
+ // only the borders have to be repainted.
+ // So we have to create 4 rectangles for every rectangle
+ // which represent the borders and then repaint them.
+
+ QRect lb,rb,tb,bb;
+ createBorderRectangles(translateToZoom(r),lb,rb,tb,bb);
+ repaintContents(lb,false);
+ repaintContents(rb,false);
+ repaintContents(tb,false);
+ repaintContents(bb,false);
+
+ createBorderRectangles(translateToZoom(oldSelectionRect),lb,rb,tb,bb);
+ repaintContents(lb,false);
+ repaintContents(rb,false);
+ repaintContents(tb,false);
+ repaintContents(bb,false);
+
+// repaintContents(oldSelectionRect | r,false);
+ oldSelectionRect = r;
+// repaintContents(translateToZoom(r),false);
+//+ imageMapEditor->updateSelection();
+
+
+// QRect r(drawStart.x(),drawStart.y(),drawCurrent.x()-drawStart.x(),drawCurrent.y()-drawStart.y());
+// r = r.normalize();
+// QRect r2(drawStart.x(),drawStart.y(),drawOld.x()-drawStart.x(),drawOld.y()-drawStart.y());
+// r2 = r2.normalize();
+// r = translateToZoom(r | r2);
+// repaintContents(r,false);
+ } else
+ if ( currentAction==None )
+ {
+ if ( imageMapEditor->selected() &&
+ imageMapEditor->selected()->onSelectionPoint(zoomedPoint,_zoom ))
+ {
+ if (imageMapEditor->selected()->type()==Area::Polygon)
+ {
+ if ((imageMapEditor->currentToolType()==KImageMapEditor::RemovePoint) &&
+ (imageMapEditor->selected()->selectionPoints()->count()>3) )
+ {
+ viewport()->setCursor(RemovePointCursor);
+ }
+ else
+ {
+ viewport()->setCursor(pointingHandCursor);
+ }
+ }
+ else
+ {
+ QPoint center=imageMapEditor->selected()->rect().center();
+ if (drawCurrent.x() < center.x()) {
+ if (drawCurrent.y() < center.y())
+ viewport()->setCursor(sizeFDiagCursor);
+ else
+ viewport()->setCursor(sizeBDiagCursor);
+ }
+ else {
+ if (drawCurrent.y() < center.y())
+ viewport()->setCursor(sizeBDiagCursor);
+ else
+ viewport()->setCursor(sizeFDiagCursor);
+ }
+ }
+ } else
+ if ( imageMapEditor->onArea(drawCurrent) )
+ {
+ if (imageMapEditor->currentToolType()==KImageMapEditor::AddPoint)
+ {
+ viewport()->setCursor(AddPointCursor);
+ }
+ else
+ {
+ viewport()->setCursor(sizeAllCursor);
+ }
+ }
+ else
+ if (imageMapEditor->currentToolType()==KImageMapEditor::Rectangle) {
+ viewport()->setCursor(RectangleCursor);
+// kdDebug() << "KImageMapEditor::DrawZone: viewport()->setCursor to Rectangle" << endl;
+ }
+ else
+ if (imageMapEditor->currentToolType()==KImageMapEditor::Circle)
+ viewport()->setCursor(CircleCursor);
+ else
+ if (imageMapEditor->currentToolType()==KImageMapEditor::Polygon)
+ viewport()->setCursor(PolygonCursor);
+ else
+ if (imageMapEditor->currentToolType()==KImageMapEditor::Freehand)
+ viewport()->setCursor(FreehandCursor);
+ else
+ viewport()->setCursor(arrowCursor);
+
+ }
+ imageMapEditor->slotChangeStatusCoords(drawCurrent.x(),drawCurrent.y());
+}
+
+void DrawZone::createBorderRectangles(const QRect & r,QRect & rb,QRect & lb,QRect & tb,QRect & bb)
+{
+ int bw;
+ bw = (int) (2+2*_zoom); // Border width
+
+ rb.setX(r.x()+r.width()-bw);
+ rb.setY(r.y());
+ rb.setWidth(bw+1);
+ rb.setHeight(r.height());
+
+ lb.setX(r.x());
+ lb.setY(r.y());
+ lb.setWidth(bw);
+ lb.setHeight(r.height());
+
+ tb.setX(r.x());
+ tb.setY(r.y());
+ tb.setWidth(r.width());
+ tb.setHeight(bw);
+
+ bb.setX(r.x());
+ bb.setY(r.y()+r.height()-bw);
+ bb.setWidth(r.width());
+ bb.setHeight(bw+1);
+}
+
+
+void DrawZone::resizeEvent(QResizeEvent* e) {
+ QScrollView::resizeEvent(e);
+ int width=(int) (image.width()*_zoom);
+ int height=(int) (image.height()*_zoom);
+ if (visibleWidth()>width)
+ width=visibleWidth();
+ if (visibleHeight()>height)
+ height=visibleHeight();
+
+ resizeContents(width,height);
+
+ imageRect.setLeft(0);
+ imageRect.setTop(0);
+ imageRect.setHeight((int)(image.height()*_zoom));
+ imageRect.setWidth((int)(image.width()*_zoom));
+
+}
+
+void DrawZone::cancelDrawing()
+{
+ if ( (currentAction == DrawPolygon )
+ || (currentAction == DrawRectangle )
+ || (currentAction == DrawCircle )
+ )
+ {
+ currentAction = None;
+ QRect r = translateToZoom(currentArea->selectionRect());
+ delete currentArea;
+ currentArea = 0L;
+ repaintContents(r,false);
+ imageMapEditor->slotUpdateSelectionCoords();
+ }
+}
+
+void DrawZone::repaintArea(const Area & a) {
+ repaintContents(translateToZoom(a.selectionRect()),false);
+}
+
+void DrawZone::repaintRect(const QRect & r) {
+ repaintContents(translateToZoom(r),false);
+}
+
+void DrawZone::drawContents(QPainter* p,int clipx,int clipy,int clipw,int cliph)
+{
+
+// Erase background without flicker
+ QRect updateRect(clipx,clipy,clipw,cliph);
+
+ // Pixmap for double-buffering
+ QPixmap doubleBuffer(updateRect.size());
+ if (doubleBuffer.isNull())
+ return;
+
+ QPainter p2(&doubleBuffer);
+ p2.drawPixmap(0,0,zoomedImage,clipx,clipy,clipw,cliph);
+ p2.setBackgroundColor(p->backgroundColor());
+
+ if (zoomedImage.width() < (clipw+clipx) ) {
+ int eraseWidth = clipw+clipx - zoomedImage.width();
+ p2.eraseRect( QRect(clipw-eraseWidth,0,eraseWidth,cliph) );
+ }
+
+ if (zoomedImage.height() < (cliph+clipy) ) {
+ int eraseHeight = cliph+clipy - zoomedImage.height();
+ p2.eraseRect( QRect(0,cliph-eraseHeight,clipw,eraseHeight) );
+ }
+
+ p2.translate(-clipx, -clipy);
+ p2.scale(_zoom,_zoom);
+
+ QRect areaUpdateRect;
+ areaUpdateRect.setX(myround(clipx/_zoom)-1);
+ areaUpdateRect.setY(myround(clipy/_zoom)-1);
+ areaUpdateRect.setWidth(myround(clipw/_zoom)+2);
+ areaUpdateRect.setHeight(myround(cliph/_zoom)+2);
+
+ AreaListIterator it=imageMapEditor->areaList();
+ for ( it.toLast();it.current() != 0L; --it)
+ {
+ if (it.current()->rect().intersects(areaUpdateRect))
+ it.current()->draw(p2);
+ }
+
+ // Draw the current drawing Area
+ if (currentAction != MoveArea &&
+ currentAction != MoveSelectionPoint &&
+ currentAction != None &&
+ currentAction != DoSelect)
+ {
+ currentArea->draw(p2);
+ }
+
+ if (currentAction == DoSelect )
+ {
+ QPen pen = QPen(QColor("white"),1);
+ p2.setRasterOp(Qt::XorROP);
+ pen.setStyle(Qt::DotLine);
+ p2.setPen(pen);
+
+ QRect r( drawStart.x(),drawStart.y(),drawCurrent.x()-drawStart.x(),drawCurrent.y()-drawStart.y());
+ r = r.normalize();
+ p2.drawRect(r);
+ }
+
+
+
+ p2.end();
+
+ // Copy the double buffer into the widget
+ p->drawPixmap(clipx,clipy,doubleBuffer);
+
+
+}
+
+void DrawZone::contentsDragEnterEvent(QDragEnterEvent*e) {
+ if (!KURLDrag::canDecode(e))
+ return;
+
+// bool accept = false;
+ KURL::List uris;
+ KURLDrag::decode(e,uris);
+ KMimeType::Ptr ptr = KMimeType::findByURL(uris.first());
+// kdDebug() << "***** " << ptr.data()->name() << endl;
+ if ((ptr.data()->name() == "text/html")
+ || (ptr.data()->name().left(6) == "image/"))
+ e->accept();
+}
+
+void DrawZone::contentsDropEvent( QDropEvent* e) {
+ viewportDropEvent(e);
+}
+
+
+
+void DrawZone::viewportDropEvent( QDropEvent* e) {
+ KURL::List urlList;
+ // A file from konqueror was dropped
+ if (KURLDrag::decode(e,urlList)) {
+ imageMapEditor->openFile(urlList.first());
+ }
+}
diff --git a/kimagemapeditor/drawzone.h b/kimagemapeditor/drawzone.h
new file mode 100644
index 00000000..764e6951
--- /dev/null
+++ b/kimagemapeditor/drawzone.h
@@ -0,0 +1,122 @@
+/***************************************************************************
+ imagemap.h - description
+ -------------------
+ begin : Wed Apr 4 2001
+ copyright : (C) 2001 by Jan Schäfer
+ email : janschaefer@users.sourceforge.net
+***************************************************************************/
+
+/***************************************************************************
+* *
+* 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. *
+* *
+***************************************************************************/
+
+#ifndef IMAGEMAP_H
+#define IMAGEMAP_H
+
+#include <qscrollview.h>
+#include <qimage.h>
+#include <qpoint.h>
+#include <qrect.h>
+#include <qcursor.h>
+
+#include "kdeversion.h"
+
+class KImageMapEditor;
+class Area;
+
+/**
+ *@short Draws the image and areas and handle the draw actions
+ *@author Jan Sch&auml;fer
+ *@internal
+ *@see Area
+ */
+class DrawZone : public QScrollView {
+public:
+
+ DrawZone(QWidget *parent,KImageMapEditor* _imageMapEditor);
+ ~DrawZone();
+
+ QImage picture() const;
+ void repaintArea(const Area & a);
+ void repaintRect(const QRect & r);
+ void cancelDrawing();
+
+ void setPicture(const QImage &_image);
+ void setZoom(double z);
+
+ QPoint translateFromZoom(const QPoint & p) const;
+ QRect translateFromZoom(const QRect & p) const;
+ QPoint translateToZoom(const QPoint & p) const;
+ QRect translateToZoom(const QRect & p) const;
+
+ QRect getImageRect() const { return image.rect(); }
+
+
+protected:
+
+ virtual void contentsMouseDoubleClickEvent(QMouseEvent*);
+ virtual void contentsMousePressEvent(QMouseEvent*);
+ virtual void contentsMouseReleaseEvent(QMouseEvent*);
+ virtual void contentsMouseMoveEvent(QMouseEvent*);
+ virtual void resizeEvent(QResizeEvent*);
+ virtual void drawContents(QPainter*,int,int,int,int);
+ virtual void viewportDropEvent(QDropEvent*);
+ virtual void contentsDragEnterEvent(QDragEnterEvent*);
+ virtual void contentsDropEvent(QDropEvent*);
+
+ /**
+ * Represents whats currently going on
+ * @li None : Nothing
+ * @li DrawCircle : The user is drawing a circle
+ * @li DrawRectangle : The user is drawing a rectangle
+ * @li MoveSelectionPoint : The user is resizing an @ref Area or moving a polygon point
+ * @li MoveArea : The user is moving an @ref Area
+ * @li DoSelect : The user makes a selection rectangle
+ */
+ enum DrawAction { None, DrawCircle, DrawRectangle, DrawPolygon, DrawFreehand, MoveSelectionPoint, MoveArea, DoSelect, RemovePoint, AddPoint };
+
+ void createBorderRectangles(const QRect & r,QRect & rb,QRect & lb,QRect & tb,QRect & bb);
+
+private:
+
+ DrawAction currentAction;
+ // The currently drawing area
+ Area *currentArea;
+ // Needed when moving selectionpoints
+ QRect *currentSelectionPoint;
+ // The point where the user clicked the mouse
+ QPoint drawStart;
+ QPoint drawCurrent;
+ // The original image
+ QImage image;
+ KImageMapEditor *imageMapEditor;
+ // Only the rect of the zoomed image, perhaps redundant
+ QRect imageRect;
+ // Only for repaint issues
+ Area *oldArea;
+
+ QRect oldSelectionRect;
+ // Holds the zoomed image for efficiency reasons
+ QPixmap zoomedImage;
+ // The current zoom-factor
+ double _zoom;
+
+ QCursor RectangleCursor;
+ QCursor CircleCursor;
+ QCursor PolygonCursor;
+ QCursor FreehandCursor;
+ QCursor AddPointCursor;
+ QCursor RemovePointCursor;
+};
+
+inline QImage DrawZone::picture() const {
+ return image;
+}
+
+
+#endif
diff --git a/kimagemapeditor/dummy.cpp b/kimagemapeditor/dummy.cpp
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/kimagemapeditor/dummy.cpp
diff --git a/kimagemapeditor/imagemap.cpp b/kimagemapeditor/imagemap.cpp
new file mode 100644
index 00000000..665ef000
--- /dev/null
+++ b/kimagemapeditor/imagemap.cpp
@@ -0,0 +1,395 @@
+/***************************************************************************
+ imagemap.cpp - description
+ -------------------
+ begin : Wed Apr 4 2001
+ copyright : (C) 2001 by Jan Schäfer
+ email : j_schaef@informatik.uni-kl.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "imagemap.h"
+#include "kimagemapeditor.h"
+#include "qpainter.h"
+#include "kdebug.h"
+#include <qbitmap.h>
+
+int round(double d) {
+ if ( (d-((int) d)) < 0.5 )
+ return (int) d;
+ else
+ return ((int) d)+1;
+}
+
+ImageMap::ImageMap(QWidget *parent,KImageMapEditor* _imageMapEditor)
+ : QScrollView(parent)
+{
+ imageMapEditor=_imageMapEditor;
+// setPicture(QImage());
+ currentAction=None;
+ currentArea=0L;
+ eraseOldArea=false;
+ oldArea=0L;
+ _zoom=1;
+ viewport()->setMouseTracking(true);
+
+
+}
+
+ImageMap::~ImageMap(){
+}
+
+void ImageMap::setPicture(const QImage &_image) {
+ image=_image;
+ zoomedImage.convertFromImage(image);
+ setZoom(_zoom);
+}
+
+void ImageMap::setZoom(double z) {
+ _zoom=z;
+ imageRect.setHeight(image.height()*_zoom);
+ imageRect.setWidth(image.width()*_zoom);
+ zoomedImage=QPixmap(imageRect.width(),imageRect.height());
+ QPainter p(&zoomedImage);
+ p.scale(z,z);
+ QPixmap pix;
+ pix.convertFromImage(image);
+ // if the picture has transparent areas,
+ // fill them with Gimp like background
+ if (pix.mask()) {
+ QPixmap backPix(32,32);
+ QPainter p2(&backPix);
+ p2.fillRect(0,0,32,32,QColor(156,149,156));
+ p2.fillRect(0,16,16,16,QColor(98,105,98));
+ p2.fillRect(16,0,16,16,QColor(98,105,98));
+ p2.flush();
+ p.setPen(QPen());
+ p.fillRect(imageRect.left(),imageRect.top(),imageRect.width(),imageRect.height(),QBrush(QColor("black"),backPix));
+ }
+ p.drawPixmap(imageRect.left(),imageRect.top(),pix);
+ p.flush();
+ resizeContents(visibleWidth()>imageRect.width() ? visibleWidth() : imageRect.width(),
+ visibleHeight()>imageRect.height() ? visibleHeight() : imageRect.height());
+ repaintContents(0,0,contentsWidth(),contentsHeight(),true);
+}
+
+QPoint ImageMap::translateFromZoom(const QPoint & p) const {
+ return QPoint(p.x()/_zoom,p.y()/_zoom);
+}
+
+QPoint ImageMap::translateToZoom(const QPoint & p) const {
+ return QPoint(round(p.x()*_zoom),round(p.y()*_zoom));
+}
+
+QRect ImageMap::translateToZoom(const QRect & r) const {
+ return QRect(round(r.x()*_zoom),round(r.y()*_zoom),
+ round(r.width()*_zoom),round(r.height()*_zoom));
+}
+
+void ImageMap::contentsMouseDoubleClickEvent(QMouseEvent* e) {
+ QPoint point=e->pos();
+ point-=imageRect.topLeft();
+ point=translateFromZoom(point);
+ if ( currentAction==None &&
+ (currentArea=imageMapEditor->onArea(point)))
+ imageMapEditor->showTagEditor(currentArea);
+
+}
+
+void ImageMap::contentsMousePressEvent(QMouseEvent* e) {
+ drawStart=e->pos();
+ // Check if it's on picture if not
+ // move it to the picture's border
+ if (!imageRect.contains(drawStart)) {
+ if (drawStart.x()>imageRect.right())
+ drawStart.setX(imageRect.right());
+ if (drawStart.x()<imageRect.left())
+ drawStart.setX(imageRect.left());
+ if (drawStart.y()>imageRect.bottom())
+ drawStart.setY(imageRect.bottom());
+ if (drawStart.y()<imageRect.top())
+ drawStart.setY(imageRect.top());
+ }
+
+ // Translate it to picture coordinates
+ drawStart-=imageRect.topLeft();
+ drawStart=translateFromZoom(drawStart);
+ if (currentArea)
+ oldArea=new Area(*currentArea);
+
+ if ( currentAction==None ) {
+ if (e->button()==RightButton) {
+ currentArea=imageMapEditor->onArea(drawStart);
+ imageMapEditor->select(currentArea);
+ imageMapEditor->slotShowPopupMenu(e->globalPos());
+ } else
+ if ((currentArea=imageMapEditor->selected()) &&
+ (currentSelectionPoint=currentArea->onSelectionPoint(drawStart)))
+ {
+ currentAction=MoveSelectionPoint;
+ } else
+ if ((currentArea=imageMapEditor->onArea(drawStart))) {
+ currentAction=MoveArea;
+ imageMapEditor->select(currentArea);
+ } else
+ if (imageMapEditor->currentShapeType()!=Area::None) {
+ currentArea=new Area(imageMapEditor->currentShapeType());
+ currentArea->setRect(QRect(drawStart,drawStart));
+ currentArea->setSelected(false);
+ if (imageMapEditor->selected())
+ imageMapEditor->selected()->setSelected(false);
+ switch (currentArea->type()) {
+ case Area::Rectangle : currentAction=DrawRectangle; break;
+ case Area::Circle : currentAction=DrawCircle; break;
+ case Area::Polygon :
+ currentAction=DrawPolygon;
+ currentArea->addCoord(drawStart);
+ currentSelectionPoint=currentArea->selectionPoints()->last();
+
+ break;
+ default: break;
+ }
+ }
+ // Clicked with the arrow at an areafree position
+ else {
+ currentArea=0L;
+ imageMapEditor->deselectAll();
+ }
+ } else
+ if ( currentAction==DrawPolygon) {
+
+ }
+
+ QRect r;
+ if (oldArea)
+ r=oldArea->selectionRect();
+ if (currentArea) {
+ r= r | currentArea->selectionRect();
+ repaintContents(translateToZoom(r),false);
+ }
+
+}
+
+void ImageMap::contentsMouseReleaseEvent(QMouseEvent *e) {
+ drawEnd=e->pos();
+
+ // Check if it's on picture if not
+ // move it to the picture's border
+ if (!imageRect.contains(drawEnd)) {
+ if (drawEnd.x()>imageRect.right())
+ drawEnd.setX(imageRect.right());
+ if (drawEnd.x()<imageRect.left())
+ drawEnd.setX(imageRect.left());
+ if (drawEnd.y()>imageRect.bottom())
+ drawEnd.setY(imageRect.bottom());
+ if (drawEnd.y()<imageRect.top())
+ drawEnd.setY(imageRect.top());
+ }
+ // Translate it to picture coordinates
+ drawEnd-=imageRect.topLeft();
+ drawEnd=translateFromZoom(drawEnd);
+
+ if (currentAction==DrawCircle || currentAction==DrawRectangle) {
+ imageMapEditor->addArea(currentArea);
+ imageMapEditor->select(currentArea);
+ //imageMapEditor->slotAreaChanged(currentArea);
+ currentAction=None;
+ } else
+ if (currentAction==DrawPolygon) {
+ // If the number of Polygonpoints is more than 2
+ // and clicked on the first PolygonPoint or
+ // the right Button was pressed the Polygon is finished
+ if ((currentArea->selectionPoints()->count()>2)
+ && (currentArea->selectionPoints()->first()->contains(drawEnd)
+ || (e->button()==RightButton)))
+ {
+ currentArea->setFinished(true);
+ imageMapEditor->addArea(currentArea);
+ currentAction=None;
+ } else
+ {
+ currentArea->addCoord(drawEnd);
+ currentSelectionPoint=currentArea->selectionPoints()->last();
+ }
+
+// currentArea->addCoord(drawEnd);
+// currentSelectionPoint=currentArea->selectionPoints()->last();
+ } else
+ if (currentAction==MoveArea || currentAction==MoveSelectionPoint) {
+ imageMapEditor->slotAreaChanged(currentArea);
+ currentAction=None;
+ }
+ else {
+ currentAction=None;
+ }
+ imageMapEditor->slotChangeStatusCoords(drawEnd.x(),drawEnd.y());
+ imageMapEditor->slotUpdateSelectionCoords();
+
+ if (currentArea)
+ repaintArea(*currentArea);
+// repaintContents(0,0,contentsWidth(),contentsHeight(),false);
+}
+
+
+void ImageMap::contentsMouseMoveEvent(QMouseEvent *e) {
+ drawCurrent=e->pos();
+
+ // If outside the image
+ // set it to the border
+ if (!imageRect.contains(drawCurrent)) {
+ if (drawCurrent.x()>imageRect.right())
+ drawCurrent.setX(imageRect.right());
+ if (drawCurrent.x()<imageRect.left())
+ drawCurrent.setX(imageRect.left());
+ if (drawCurrent.y()>imageRect.bottom())
+ drawCurrent.setY(imageRect.bottom());
+ if (drawCurrent.y()<imageRect.top())
+ drawCurrent.setY(imageRect.top());
+ }
+
+ // Translate to image coordinates
+ drawCurrent-=imageRect.topLeft();
+ drawCurrent=translateFromZoom(drawCurrent);
+
+ if (currentAction==DrawRectangle) {
+ // To avoid flicker, only repaint the minimum rect
+ QRect oldRect=translateToZoom(currentArea->rect());
+ currentArea->setRect(QRect(drawStart,drawCurrent).normalize());
+ QRect newRect=translateToZoom(currentArea->rect());
+ QRect r=oldRect | newRect;
+ repaintContents(r,false);
+ imageMapEditor->slotUpdateSelectionCoords(currentArea->rect());
+ } else
+ if (currentAction==DrawCircle) {
+ QRect oldRect=translateToZoom(currentArea->rect());
+ currentArea->setRect(QRect(drawStart,drawCurrent).normalize());
+ QRect newRect=translateToZoom(currentArea->rect());
+ QRect r=oldRect | newRect;
+ repaintContents(r,false);
+ imageMapEditor->slotUpdateSelectionCoords(currentArea->rect());
+ } else
+ if ( currentAction==DrawPolygon ) {
+ QRect oldRect=translateToZoom(currentArea->rect());
+ currentArea->moveSelectionPoint(currentSelectionPoint,drawCurrent);
+ QRect newRect=translateToZoom(currentArea->rect());
+ QRect r=oldRect | newRect;
+ repaintContents(r,false);
+ imageMapEditor->slotUpdateSelectionCoords(currentArea->rect());
+ } else
+ if ( currentAction==MoveArea ) {
+ QRect oldRect=translateToZoom(currentArea->selectionRect());
+ currentArea->moveBy((drawCurrent-drawStart).x(),(drawCurrent-drawStart).y());
+ QRect newRect=translateToZoom(currentArea->selectionRect());
+ QRect r=oldRect | newRect;
+ repaintContents(r,false);
+ drawStart=drawCurrent;
+ imageMapEditor->slotUpdateSelectionCoords();
+ } else
+ if ( currentAction==MoveSelectionPoint ) {
+ QRect oldRect=translateToZoom(currentArea->selectionRect());
+ currentArea->moveSelectionPoint(currentSelectionPoint,drawCurrent);
+ QRect newRect=translateToZoom(currentArea->selectionRect());
+ QRect r=oldRect | newRect;
+ repaintContents(r,false);
+ imageMapEditor->slotUpdateSelectionCoords();
+ }
+ imageMapEditor->slotChangeStatusCoords(drawCurrent.x(),drawCurrent.y());
+}
+
+void ImageMap::resizeEvent(QResizeEvent* e) {
+ QScrollView::resizeEvent(e);
+ int width=(int) (image.width()*_zoom);
+ int height=(int) (image.height()*_zoom);
+ if (visibleWidth()>width)
+ width=visibleWidth();
+ if (visibleHeight()>height)
+ height=visibleHeight();
+
+ resizeContents(width,height);
+
+ imageRect.setLeft(0);
+ imageRect.setTop(0);
+ imageRect.setHeight(image.height()*_zoom);
+ imageRect.setWidth(image.width()*_zoom);
+
+}
+
+void ImageMap::repaintArea(const Area & a) {
+ repaintContents(translateToZoom(a.selectionRect()),false);
+}
+
+void ImageMap::drawContents(QPainter* p,int clipx,int clipy,int clipw,int cliph) {
+// kdDebug() << "drawing\n" << endl;
+// p.scale(rect.width()*2,rect.height()*2);
+// if (e->rect()!=rect()) {
+// p.setClipping(true);
+// p.setClipRect(e->rect());
+// } else
+/* if (currentAction==DrawRectangle) {
+ p->setClipping(true);
+ QRect r(currentArea->rect());
+ r.moveBy(imageRect.left()-5,imageRect.top()-5);
+ r.setSize(r.size()+QSize(10,10));
+ p->setClipRegion(r);
+ }
+*/
+
+ QRect updateRect(clipx,clipy,clipw,cliph);
+ QPixmap doubleBuffer(updateRect.size()); // Pixmap for double-buffering
+ QPainter p2(&doubleBuffer);
+ p2.drawPixmap(0,0,zoomedImage,clipx,clipy,clipw,cliph);
+ p2.translate(-updateRect.x(), -updateRect.y());
+ p2.scale(_zoom,_zoom);
+
+ AreaList *list=imageMapEditor->areaList();
+ for (Area* s=list->first();s != 0L; s=list->next())
+ s->draw(p2);
+
+ // Draw the current drawing Area
+ if (currentAction != MoveArea &&
+ currentAction != MoveSelectionPoint &&
+ currentAction != None)
+ {
+ currentArea->draw(p2);
+ }
+
+ p2.end();
+
+ // Copy the double buffer into the widget
+ p->drawPixmap(clipx,clipy,doubleBuffer);
+ // Erase background without flicker
+ QRegion region(contentsX(),contentsY(),visibleWidth(),visibleHeight());
+ region=region.subtract(QRegion(imageRect));
+ for (int i=0;i<region.rects().count();i++) {
+ p->eraseRect(region.rects()[i]);
+ }
+
+
+ // Draw our picture
+// p->drawPixmap(imageRect.left(),imageRect.top(),zoomedImage);
+//
+//
+// p->scale(_zoom,_zoom);
+// p->translate(imageRect.left(),imageRect.top());
+//
+// AreaList *list=imageMapEditor->areaList();
+// for (Area* s=list->first();s != 0L; s=list->next())
+// s->draw(*p);
+//
+// // Draw the current drawing Area
+// if (currentAction != MoveArea &&
+// currentAction != MoveSelectionPoint &&
+// currentAction != None)
+// {
+// currentArea->draw(*p);
+// }
+
+
+}
diff --git a/kimagemapeditor/imagemap.h b/kimagemapeditor/imagemap.h
new file mode 100644
index 00000000..7576baa0
--- /dev/null
+++ b/kimagemapeditor/imagemap.h
@@ -0,0 +1,77 @@
+/***************************************************************************
+ imagemap.h - description
+ -------------------
+ begin : Wed Apr 4 2001
+ copyright : (C) 2001 by Jan Schäfer
+ email : janschaefer@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef IMAGEMAP_H
+#define IMAGEMAP_H
+
+#include <qscrollview.h>
+#include <qimage.h>
+#include <qpoint.h>
+#include <qrect.h>
+
+#include "kdeversion.h"
+
+/**
+ *@author Jan Schäfer
+ */
+class KImageMapEditor;
+class Area;
+
+class ImageMap : public QScrollView {
+public:
+ enum DrawAction { None, DrawCircle, DrawRectangle, DrawPolygon, MoveSelectionPoint, MoveArea };
+private:
+ QRect imageRect;
+ QPoint drawStart;
+ QPoint drawCurrent;
+ QPoint drawEnd;
+ bool eraseOldArea;
+ Area *oldArea;
+ // Holds the original image
+ QImage image;
+ // Holds the zoomed image for efficiency reasons
+ QPixmap zoomedImage;
+ Area *currentArea;
+ DrawAction currentAction;
+ QRect *currentSelectionPoint;
+ KImageMapEditor *imageMapEditor;
+ double _zoom;
+public:
+ ImageMap(QWidget *parent,KImageMapEditor* _imageMapEditor);
+ ~ImageMap();
+ void setZoom(double z);
+ void setPicture(const QImage &_image);
+ void repaintArea(const Area & a);
+ QImage picture() const;
+ QPoint translateFromZoom(const QPoint & p) const;
+ QPoint translateToZoom(const QPoint & p) const;
+ QRect translateToZoom(const QRect & p) const;
+protected:
+ virtual void contentsMousePressEvent(QMouseEvent* e);
+ virtual void contentsMouseDoubleClickEvent(QMouseEvent* e);
+ virtual void contentsMouseReleaseEvent(QMouseEvent *e);
+ virtual void contentsMouseMoveEvent(QMouseEvent *e);
+ virtual void resizeEvent(QResizeEvent* e);
+ virtual void drawContents(QPainter* p,int clipx,int clipy,int clipw,int cliph);
+};
+
+inline QImage ImageMap::picture() const {
+ return image;
+}
+
+
+#endif
diff --git a/kimagemapeditor/imageslistview.cpp b/kimagemapeditor/imageslistview.cpp
new file mode 100644
index 00000000..55992101
--- /dev/null
+++ b/kimagemapeditor/imageslistview.cpp
@@ -0,0 +1,157 @@
+/***************************************************************************
+ imageslistview.cpp - description
+ -------------------
+ begin : Weg Feb 26 2003
+ copyright : (C) 2003 by Jan Schäfer
+ email : janschaefer@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+// QT
+#include <qptrlist.h>
+
+
+// KDE
+#include <klocale.h>
+#include <kdebug.h>
+
+// locale
+#include "imageslistview.h"
+
+ImagesListViewItem::ImagesListViewItem(ImagesListView* parent, ImageTag* tag)
+ : QListViewItem(parent)
+{
+ _imageTag = tag;
+ update();
+}
+
+
+void ImagesListViewItem::update() {
+ QString src="";
+ QString usemap="";
+ if (_imageTag->find("src"))
+ src=*_imageTag->find("src");
+ if (_imageTag->find("usemap"))
+ usemap=*_imageTag->find("usemap");
+
+ setText(0,src);
+ setText(1,usemap);
+}
+
+ImageTag* ImagesListViewItem::imageTag() {
+ return _imageTag;
+}
+
+
+ImagesListView::ImagesListView(QWidget *parent, const char *name)
+ : KListView(parent, name)
+{
+ addColumn(i18n("Images"));
+ addColumn(i18n("Usemap"));
+ //addColumn(i18n("Preview"));
+ setFullWidth(true);
+
+
+ connect( this, SIGNAL( selectionChanged(QListViewItem*)),
+ this, SLOT( slotSelectionChanged(QListViewItem*)));
+}
+
+
+ImagesListView::~ImagesListView()
+{
+}
+
+void ImagesListView::addImage(ImageTag* tag)
+{
+ if (!tag) {
+ kdDebug() << "ImageListView::addImage: Parameter is null !" << endl;
+ return;
+ }
+
+ new ImagesListViewItem(this, tag);
+}
+
+void ImagesListView::addImages(QPtrList<ImageTag> * images)
+{
+ for (ImageTag *tag = images->first(); tag!=0L; tag=images->next()) {
+ addImage(tag);
+ }
+}
+
+void ImagesListView::clear() {
+ QListView::clear();
+}
+
+void ImagesListView::removeImage(ImageTag* tag) {
+ ImagesListViewItem *item = findListViewItem(tag);
+ if (item) {
+ takeItem(item);
+ setSelected(currentItem(),true);
+ }
+ else {
+ kdDebug() << "ImageListView::removeImage: ListViewItem was not found !" << endl;
+ }
+}
+
+void ImagesListView::updateImage(ImageTag* tag) {
+ ImagesListViewItem *item = findListViewItem(tag);
+ if (item)
+ item->update();
+ else {
+ kdDebug() << "ImageListView::updateImage: ListViewItem was not found !" << endl;
+ }
+}
+
+ImagesListViewItem* ImagesListView::findListViewItem(ImageTag* tag) {
+
+ kdDebug() << "ImageListView::findListViewItem: start searching ... " << endl;
+
+ for (QListViewItem* item = firstChild(); item ; item = item->nextSibling()) {
+ ImagesListViewItem *imageItem = static_cast<ImagesListViewItem*>(item);
+ if (imageItem->imageTag() == tag) {
+ kdDebug() << "ImageListView::findListViewItem: found it " << endl;
+
+ return imageItem;
+ }
+ }
+
+ kdDebug() << "ImageListView::findListViewItem: found nothing " << endl;
+ return 0L;
+
+}
+
+void ImagesListView::slotSelectionChanged(QListViewItem* item) {
+ QString src = item->text(0);
+
+ emit imageSelected(KURL(_baseUrl,src));
+}
+
+ImageTag* ImagesListView::selectedImage() {
+ ImagesListViewItem* item = static_cast<ImagesListViewItem*>(selectedItem());
+ if ( ! item) {
+ kdDebug() << "ImagesListView::selectedImage: No Image is selected !" << endl;
+ return 0L;
+ }
+
+ return item->imageTag();
+
+
+}
+
+void ImagesListView::selectImage(ImageTag* tag) {
+ ImagesListViewItem* item = findListViewItem(tag);
+ if (item) {
+ setSelected(item, true);
+ }
+}
+
+#include "imageslistview.moc"
+
diff --git a/kimagemapeditor/imageslistview.h b/kimagemapeditor/imageslistview.h
new file mode 100644
index 00000000..55680405
--- /dev/null
+++ b/kimagemapeditor/imageslistview.h
@@ -0,0 +1,111 @@
+/***************************************************************************
+ imageslistview.h - description
+ -------------------
+ begin : Weg Feb 26 2003
+ copyright : (C) 2003 by Jan Schäfer
+ email : janschaefer@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef _IMAGESLISTVIEW_H_
+#define _IMAGESLISTVIEW_H_
+
+#include <klistview.h>
+#include <kurl.h>
+
+#include "kimagemapeditor.h"
+
+class ImagesListView;
+
+class ImagesListViewItem : public QListViewItem
+{
+ public:
+ ImagesListViewItem(ImagesListView*, ImageTag*);
+ ImageTag* imageTag();
+
+ /**
+ * Re-reads the contents of the ImageTag and updates
+ * itself accordingly
+ */
+ void update();
+ protected:
+ ImageTag* _imageTag;
+};
+
+/**
+ * Simple class that shows a list of imagenames with a preview
+ * Jan Schaefer
+ **/
+class ImagesListView : public KListView
+{
+ Q_OBJECT
+
+public:
+ ImagesListView(QWidget *parent, const char *name);
+ virtual ~ImagesListView();
+
+ /**
+ * Adds an image
+ */
+ void addImage(ImageTag*);
+
+ /**
+ * Adds images
+ */
+ void addImages(QPtrList<ImageTag> *);
+
+ /**
+ * Removes the given image from the list
+ */
+ void removeImage(ImageTag*);
+
+ /**
+ * Updates the listview item with the given ImageTag
+ */
+ void updateImage(ImageTag*);
+
+ /**
+ * Removes all images
+ */
+ void clear();
+
+ /**
+ * Returns the filename of the current selected Image
+ */
+ ImageTag* selectedImage();
+
+ /**
+ * Selects the given image
+ */
+ void selectImage(ImageTag*);
+
+ /**
+ * Sets the base URL of all images
+ */
+ void setBaseUrl(const KURL & url) { _baseUrl = url; };
+
+protected slots:
+ void slotSelectionChanged(QListViewItem*);
+
+signals:
+ void imageSelected(const KURL &);
+
+protected:
+ KURL _baseUrl;
+
+ /**
+ * Finds the first ImageListViewItem with the given ImageTag
+ * Returns 0L if no item was found
+ */
+ ImagesListViewItem* findListViewItem(ImageTag*);
+};
+
+#endif
diff --git a/kimagemapeditor/kimagemapeditor.cpp b/kimagemapeditor/kimagemapeditor.cpp
new file mode 100644
index 00000000..ebfb0c7f
--- /dev/null
+++ b/kimagemapeditor/kimagemapeditor.cpp
@@ -0,0 +1,2819 @@
+/***************************************************************************
+ imagemapeditor.cpp - description
+ -------------------
+ begin : Wed Apr 4 2001
+ copyright : (C) 2001 by Jan Sch�er
+ email : j_schaef@informatik.uni-kl.de
+***************************************************************************/
+
+/***************************************************************************
+* *
+* 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. *
+* *
+***************************************************************************/
+
+#include <iostream>
+#include <assert.h>
+
+// QT
+#include <qlayout.h>
+#include <qlistview.h>
+#include <qpushbutton.h>
+#include <qvbox.h>
+#include <qpixmap.h>
+#include <qcombobox.h>
+#include <qsplitter.h>
+#include <qfileinfo.h>
+#include <qmultilineedit.h>
+#include <qtextstream.h>
+#include <qpopupmenu.h>
+#include <qdict.h>
+#include <qwhatsthis.h>
+#include <qtooltip.h>
+#include <qpainter.h>
+#include <qtabwidget.h>
+#include <qfontdatabase.h>
+#include <qfile.h>
+
+// KDE
+#include <kcommand.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kaction.h>
+#include <kaccel.h>
+#include <kstdaction.h>
+#include <kiconloader.h>
+#include <kfiledialog.h>
+#include <kmessagebox.h>
+#include <kapplication.h>
+#include <kkeydialog.h>
+#include <kedittoolbar.h>
+#include <klineeditdlg.h>
+#include <kglobal.h>
+#include <kstandarddirs.h>
+#include <kstatusbar.h>
+#include <kxmlguifactory.h>
+#include <kdockwidget.h>
+#include <kio/job.h>
+#if KDE_IS_VERSION(3,1,90)
+#include <kinputdialog.h>
+#else
+#include <qinputdialog.h>
+#endif
+
+// local
+#include "kimagemapeditor.h"
+#include "kimagemapeditor.moc"
+#include "drawzone.h"
+#include "kimedialogs.h"
+#include "kimecommands.h"
+#include "qextfileinfo.h"
+#include "areacreator.h"
+#include "arealistview.h"
+#include "imageslistview.h"
+#include "mapslistview.h"
+#include "kimecommon.h"
+
+#include <kparts/genericfactory.h>
+#include <kinstance.h>
+
+// Factory code for KDE 3
+typedef KParts::GenericFactory<KImageMapEditor> KimeFactory;
+K_EXPORT_COMPONENT_FACTORY( libkimagemapeditor , KimeFactory )
+
+KImageMapEditor::KImageMapEditor(QWidget *parentWidget, const char *,
+ QObject *parent, const char *name, const QStringList & )
+ : KParts::ReadWritePart(parent,name)
+{
+ setInstance( KimeFactory::instance() );
+
+// KDockMainWindow* mainWidget;
+
+ // Test if the MainWindow can handle DockWindows, if so create DockWidgets
+ // instead of a Splitter
+ mainDock = dynamic_cast<KDockMainWindow*>(parent) ;
+ QSplitter * splitter = 0L;
+ tabWidget = 0L;
+
+ if (mainDock) {
+// kdDebug() << "KImageMapEditor: We got a KDockMainWindow !" << endl;
+
+ KDockWidget* parentDock = mainDock->getMainDockWidget();
+ areaDock = mainDock->createDockWidget( "Areas", 0L, 0L, i18n("Areas"), i18n("Areas"));
+ mapsDock = mainDock->createDockWidget( "Maps", 0L, 0L, i18n("Maps"), i18n("Maps"));
+ imagesDock = mainDock->createDockWidget( "Images", 0L, 0L, i18n("Images"), i18n("Images"));
+
+ areaListView = new AreaListView(areaDock,"AreaListView");
+ mapsListView = new MapsListView(mapsDock, "MapsListView");
+ imagesListView = new ImagesListView(imagesDock, "ImagesListView");
+
+ areaDock->setWidget(areaListView);
+ mapsDock->setWidget(mapsListView);
+ imagesDock->setWidget(imagesListView);
+
+ areaDock->manualDock( (KDockWidget*) parentDock, KDockWidget::DockLeft, 30);
+ mapsDock->manualDock( (KDockWidget*) areaDock, KDockWidget::DockCenter);
+ imagesDock->manualDock( (KDockWidget*) mapsDock, KDockWidget::DockCenter);
+
+ connect( mainDock->manager(), SIGNAL(change()), this, SLOT(dockingStateChanged()));
+ }
+ else
+ {
+ areaDock = 0L;
+ mapsDock = 0L;
+ imagesDock = 0L;
+ splitter = new QSplitter(parentWidget);
+ tabWidget = new QTabWidget(splitter);
+ areaListView = new AreaListView(tabWidget,"AreaListView");
+ mapsListView = new MapsListView(tabWidget, "MapsListView");
+ imagesListView = new ImagesListView(tabWidget, "ImagesListView");
+
+ tabWidget->addTab(areaListView,i18n("Areas"));
+ tabWidget->addTab(mapsListView,i18n("Maps"));
+ tabWidget->addTab(imagesListView,i18n("Images"));
+ }
+
+
+ connect( areaListView->listView, SIGNAL(selectionChanged()), this, SLOT(slotSelectionChanged()));
+ connect( areaListView->listView, SIGNAL(doubleClicked(QListViewItem*)), this, SLOT(showTagEditor(QListViewItem*)));
+ connect( areaListView->listView, SIGNAL(rightButtonPressed(QListViewItem*,const QPoint &,int)), this,
+ SLOT(slotShowPopupMenu(QListViewItem*,const QPoint &)));
+
+ connect( mapsListView, SIGNAL( mapSelected(const QString &)),
+ this, SLOT( setMap(const QString &)));
+
+ connect( mapsListView, SIGNAL( mapRenamed(const QString &)),
+ this, SLOT( setMapName(const QString &)));
+
+ connect( mapsListView->listView(), SIGNAL(rightButtonPressed(QListViewItem*,const QPoint &,int)), this,
+ SLOT(slotShowMapPopupMenu(QListViewItem*,const QPoint &)));
+
+ connect( imagesListView, SIGNAL( imageSelected(const KURL &)),
+ this, SLOT( setPicture(const KURL &)));
+
+ connect( imagesListView, SIGNAL(rightButtonPressed(QListViewItem*,const QPoint &,int)), this,
+ SLOT(slotShowImagePopupMenu(QListViewItem*,const QPoint &)));
+
+ // Shows the text:
+ // "Drop an image or html file"
+/* QString path = KGlobal::dirs()->findResourceDir( "data", "kimagemapeditor/dropimage.png" ) + "kimagemapeditor/dropimage.png";
+ if ( ! QFileInfo(path).exists() ) {
+ kdError() << "Couldn't find needed dropimage.png file in "
+ "the data directory of KImageMapEditor.\n"
+ "Perhaps you have forgotten to do a make install !" << endl;
+ exit(1);
+ }
+*/
+
+ if (splitter) {
+ drawZone = new DrawZone(splitter,this);
+ splitter->setResizeMode(drawZone,QSplitter::Stretch);
+ splitter->setResizeMode(tabWidget,QSplitter::KeepSize);
+ setWidget(splitter);
+ } else {
+ drawZone = new DrawZone(parentWidget,this);
+ setWidget(drawZone);
+ }
+
+
+ areas = new AreaList();
+ currentSelected= new AreaSelection();
+ _currentToolType=KImageMapEditor::Selection;
+ copyArea=0L;
+ defaultArea=0L;
+ currentMapElement = 0L;
+
+ setupActions();
+ setupStatusBar();
+
+ setXMLFile("kimagemapeditorpartui.rc");
+
+ setPicture(getBackgroundImage());
+ _htmlContent.setAutoDelete(true);
+
+ init();
+ readConfig();
+}
+
+KImageMapEditor::~KImageMapEditor() {
+ writeConfig();
+
+ #if KDE_VERSION < 300
+ delete accel;
+ #endif
+ delete areas;
+
+ delete currentSelected;
+ delete copyArea;
+ delete defaultArea;
+
+ // Delete our DockWidgets
+ if (areaDock) {
+ areaDock->hide();
+ mapsDock->hide();
+ imagesDock->hide();
+
+ delete areaDock;
+ delete mapsDock;
+ delete imagesDock;
+ }
+
+}
+
+MapTag::MapTag() {
+ modified = false;
+ name = QString::null;
+}
+
+void KImageMapEditor::init()
+{
+ _htmlContent.clear();
+ _imageUrl = QString::null;
+ m_url = QString::null;
+ HtmlElement* el = new HtmlElement("<html>\n");
+ _htmlContent.append(el);
+ el = new HtmlElement("<head>\n");
+ _htmlContent.append(el);
+ el = new HtmlElement("</head>\n");
+ _htmlContent.append(el);
+ el = new HtmlElement("<body>\n");
+ _htmlContent.append(el);
+
+ addMap(i18n("unnamed"));
+
+ el = new HtmlElement("</body>\n");
+ _htmlContent.append(el);
+ el = new HtmlElement("</html>\n");
+ _htmlContent.append(el);
+
+ setImageActionsEnabled(false);
+}
+
+KAboutData* KImageMapEditor::createAboutData()
+{
+ KAboutData* aboutData =
+ new KAboutData( "kimagemapeditor", I18N_NOOP("KImageMapEditor"),
+ "1.0", I18N_NOOP( "An HTML imagemap editor" ),
+ KAboutData::License_GPL,
+ "(c) 2001-2003 Jan Sch&auml;fer <janschaefer@users.sourceforge.net>");
+ return aboutData;
+}
+
+
+void KImageMapEditor::setReadWrite(bool)
+{
+
+ // For now it doesn't matter if its readwrite or readonly
+ // it is always readwrite, because Quanta only supports ReadOnlyParts
+ // at this moment and in that case it should be readwrite, too.
+ ReadWritePart::setReadWrite(true);
+ /*
+ if (rw)
+ ;
+ else
+ {
+ actionCollection()->remove(arrowAction);
+ actionCollection()->remove(circleAction);
+ actionCollection()->remove(rectangleAction);
+ actionCollection()->remove(polygonAction);
+ actionCollection()->remove(freehandAction);
+ actionCollection()->remove(addPointAction);
+ actionCollection()->remove(removePointAction);
+
+ actionCollection()->remove(cutAction);
+ actionCollection()->remove(deleteAction);
+ actionCollection()->remove(copyAction);
+ actionCollection()->remove(pasteAction);
+
+ actionCollection()->remove(mapNewAction);
+ actionCollection()->remove(mapDeleteAction);
+ actionCollection()->remove(mapNameAction);
+ actionCollection()->remove(mapDefaultAreaAction);
+
+ actionCollection()->remove(areaPropertiesAction);
+
+ actionCollection()->remove(moveLeftAction);
+ actionCollection()->remove(moveRightAction);
+ actionCollection()->remove(moveUpAction);
+ actionCollection()->remove(moveDownAction);
+
+ actionCollection()->remove(increaseWidthAction);
+ actionCollection()->remove(decreaseWidthAction);
+ actionCollection()->remove(increaseHeightAction);
+ actionCollection()->remove(decreaseHeightAction);
+
+ actionCollection()->remove(toFrontAction);
+ actionCollection()->remove(toBackAction);
+ actionCollection()->remove(forwardOneAction);
+ actionCollection()->remove(backOneAction);
+
+ actionCollection()->remove(imageRemoveAction);
+ actionCollection()->remove(imageAddAction);
+ actionCollection()->remove(imageUsemapAction);
+
+ }
+ */
+
+}
+
+void KImageMapEditor::setModified(bool modified)
+{
+ // get a handle on our Save action and make sure it is valid
+ KAction *save = actionCollection()->action(KStdAction::stdName(KStdAction::Save));
+ if (!save)
+ return;
+
+ // if so, we either enable or disable it based on the current
+ // state
+ if (modified)
+ save->setEnabled(true);
+ else
+ save->setEnabled(false);
+
+ // in any event, we want our parent to do it's thing
+ ReadWritePart::setModified(modified);
+}
+
+
+KConfig *KImageMapEditor::config()
+{
+ return KimeFactory::instance()->config();
+}
+
+void KImageMapEditor::readConfig(KConfig* config) {
+ recentFilesAction->loadEntries(config,"Data");
+}
+
+void KImageMapEditor::writeConfig(KConfig* config) {
+ config->writeEntry("highlightareas",highlightAreasAction->isChecked());
+ config->writeEntry("showalt",showAltAction->isChecked());
+ recentFilesAction->saveEntries(config,"Data");
+ saveLastURL(config);
+
+}
+
+void KImageMapEditor::readConfig() {
+ config()->setGroup("General Options");
+ readConfig(config());
+ slotConfigChanged();
+}
+
+void KImageMapEditor::writeConfig() {
+ config()->setGroup("General Options");
+ writeConfig(config());
+ config()->sync();
+}
+
+
+void KImageMapEditor::saveProperties(KConfig *config)
+{
+ saveLastURL(config);
+}
+
+void KImageMapEditor::readProperties(KConfig * config)
+{
+ openLastURL(config);
+}
+
+void KImageMapEditor::slotConfigChanged()
+{
+ config()->setGroup("Appearance");
+ int newHeight=config()->readNumEntry("maximum-preview-height",50);
+ config()->setGroup("General Options");
+ _commandHistory->setUndoLimit(config()->readNumEntry("undo-level",20));
+ _commandHistory->setRedoLimit(config()->readNumEntry("redo-level",20));
+ Area::highlightArea = config()->readBoolEntry("highlightareas",true);
+ highlightAreasAction->setChecked(Area::highlightArea);
+ Area::showAlt = config()->readBoolEntry("showalt",true);
+ showAltAction->setChecked(Area::showAlt);
+
+ // if the image preview size changed update all images
+ if (maxAreaPreviewHeight!=newHeight) {
+ maxAreaPreviewHeight=newHeight;
+ }
+
+ updateAllAreas();
+ drawZone->viewport()->repaint();
+}
+
+void KImageMapEditor::openLastURL(KConfig* config) {
+ KURL lastURL ( config->readPathEntry("lastopenurl") );
+ QString lastMap = config->readEntry("lastactivemap");
+ QString lastImage = config->readPathEntry("lastactiveimage");
+
+
+// kdDebug() << "loading from group : " << config->group() << endl;
+
+// kdDebug() << "loading entry lastopenurl : " << lastURL.path() << endl;
+// KMessageBox::information(0L, config->group()+" "+lastURL.path());
+ if (!lastURL.isEmpty()) {
+// kdDebug() << "opening HTML file with map " << lastMap << " and image " << lastImage << endl;
+ if ( openHTMLFile(lastURL, lastMap, lastImage) )
+ m_url = lastURL;
+ else
+ m_url = QString::null;
+ }
+}
+
+void KImageMapEditor::saveLastURL(KConfig* config) {
+ config->writePathEntry("lastopenurl",url().path());
+ config->writeEntry("lastactivemap",mapName());
+ config->writePathEntry("lastactiveimage",_imageUrl.path());
+// kdDebug() << "writing entry lastopenurl : " << url().path() << endl;
+// kdDebug() << "writing entry lastactivemap : " << mapName() << endl;
+// kdDebug() << "writing entry lastactiveimage : " << _imageUrl.path() << endl;
+ //KMessageBox::information(0L, QString("Group: %1 Saving ... %2").arg(config->group()).arg(url().path()));
+}
+
+void KImageMapEditor::setupActions()
+{
+ // File Open
+ KAction *temp=KStdAction::open(this, SLOT(fileOpen()), actionCollection());
+ QMimeSourceFactory::defaultFactory()->setPixmap( "openimage", SmallIcon("fileopen") );
+ temp->setWhatsThis(i18n("<h3>Open File</h3>Click this to <em>open</em> a new picture or HTML file."));
+ temp->setToolTip(i18n("Open new picture or HTML file"));
+
+ // File Open Recent
+ recentFilesAction = KStdAction::openRecent(this, SLOT(openURL(const KURL&)),
+ actionCollection());
+ // File Save
+ temp =KStdAction::save(this, SLOT(fileSave()), actionCollection());
+ QMimeSourceFactory::defaultFactory()->setPixmap( "saveimage", SmallIcon("filesave") );
+ temp->setWhatsThis(i18n("<h3>Save File</h3>Click this to <em>save</em> the changes to the HTML file."));
+ temp->setToolTip(i18n("Save HTML file"));
+
+
+ // File Save As
+ (void)KStdAction::saveAs(this, SLOT(fileSaveAs()), actionCollection());
+
+ // File Close
+ temp=KStdAction::close(this, SLOT(fileClose()), actionCollection());
+ QMimeSourceFactory::defaultFactory()->setPixmap( "closeimage", SmallIcon("fileclose") );
+ temp->setWhatsThis(i18n("<h3>Close File</h3>Click this to <em>close</em> the currently open HTML file."));
+ temp->setToolTip(i18n("Close HTML file"));
+
+ // Edit Copy
+ copyAction=KStdAction::copy(this, SLOT(slotCopy()), actionCollection());
+ QMimeSourceFactory::defaultFactory()->setPixmap( "editcopyimage", SmallIcon("editcopy") );
+ copyAction->setWhatsThis(i18n("<h3>Copy</h3>"
+ "Click this to <em>copy</em> the selected area."));
+ copyAction->setEnabled(false);
+
+ // Edit Cut
+ cutAction=KStdAction::cut(this, SLOT(slotCut()), actionCollection());
+ QMimeSourceFactory::defaultFactory()->setPixmap( "editcutimage", SmallIcon("editcut") );
+ cutAction->setWhatsThis(i18n("<h3>Cut</h3>"
+ "Click this to <em>cut</em> the selected area."));
+ cutAction->setEnabled(false);
+
+ // Edit Paste
+ pasteAction=KStdAction::paste(this, SLOT(slotPaste()), actionCollection());
+ QMimeSourceFactory::defaultFactory()->setPixmap( "editpasteimage", SmallIcon("editpaste") );
+ pasteAction->setWhatsThis(i18n("<h3>Paste</h3>"
+ "Click this to <em>paste</em> the copied area."));
+ pasteAction->setEnabled(false);
+
+
+ // Edit Delete
+ deleteAction=new KAction(i18n("&Delete"), "editdelete",
+ Key_Delete,this,SLOT (slotDelete()),actionCollection(), "edit_delete");
+ QMimeSourceFactory::defaultFactory()->setPixmap( "editdeleteimage", SmallIcon("editdelete") );
+ deleteAction->setWhatsThis(i18n("<h3>Delete</h3>"
+ "Click this to <em>delete</em> the selected area."));
+ deleteAction->setEnabled(false);
+
+ // Edit Undo/Redo
+ _commandHistory = new KCommandHistory( actionCollection(), true);
+
+ // Edit Properties
+ areaPropertiesAction= new KAction(i18n("Pr&operties"),0,this,SLOT(showTagEditor()),
+ actionCollection(), "edit_properties");
+ areaPropertiesAction->setEnabled(false);
+
+ // View Zoom In
+ zoomInAction=KStdAction::zoomIn(this, SLOT(slotZoomIn()), actionCollection());
+ // View Zoom Out
+ zoomOutAction=KStdAction::zoomOut(this, SLOT(slotZoomOut()), actionCollection());
+
+ // View Zoom
+ zoomAction=new KSelectAction(i18n("Zoom"), 0,this,SLOT (slotZoom()),
+ actionCollection(), "view_zoom");
+ zoomAction->setWhatsThis(i18n("<h3>Zoom</h3>"
+ "Choose the desired zoom level."));
+ zoomAction->setItems(QStringList()
+ << i18n("25%")
+ << i18n("50%")
+ << i18n("100%")
+ << i18n("150%")
+ << i18n("200%")
+ << i18n("250%")
+ << i18n("300%")
+ << i18n("500%")
+ << i18n("750%")
+ << i18n("1000%"));
+
+ zoomAction->setCurrentItem(2);
+
+ highlightAreasAction = new KToggleAction(i18n("Highlight Areas"),0, this, SLOT (slotHightlightAreas()),
+ actionCollection(), "view_highlightareas");
+
+ showAltAction = new KToggleAction(i18n("Show Alt Tag"),0, this, SLOT (slotShowAltTag()),
+ actionCollection(), "view_showalt");
+#if KDE_IS_VERSION(3,2,90)
+ showAltAction->setCheckedState(i18n("Hide Alt Tag"));
+#endif
+
+ mapNameAction= new KAction(i18n("Map &Name..."),0,this,SLOT(mapEditName()),
+ actionCollection(), "map_name");
+
+ mapNewAction = new KAction(i18n("Ne&w Map..."),0,this,SLOT(mapNew()),
+ actionCollection(), "map_new");
+ mapNewAction->setToolTip(i18n("Create a new map"));
+
+ mapDeleteAction = new KAction(i18n("D&elete Map"),0,this,SLOT(mapDelete()),
+ actionCollection(), "map_delete");
+ mapDeleteAction->setToolTip(i18n("Delete the current active map"));
+
+ mapDefaultAreaAction = new KAction(i18n("Edit &Default Area..."),0,this,SLOT(mapDefaultArea()),
+ actionCollection(), "map_defaultarea");
+ mapDefaultAreaAction->setToolTip(i18n("Edit the default area of the current active map"));
+
+ temp = new KAction(i18n("&Preview"),0,this,SLOT(mapPreview()),
+ actionCollection(), "map_preview");
+ temp->setToolTip(i18n("Show a preview"));
+
+ // IMAGE
+ i18n("&Image");
+
+ imageAddAction = new KAction(i18n("Add Image..."),0,this,SLOT(imageAdd()),
+ actionCollection(), "image_add");
+ imageAddAction->setToolTip(i18n("Add a new image"));
+
+ imageRemoveAction = new KAction(i18n("Remove Image"),0,this,SLOT(imageRemove()),
+ actionCollection(), "image_remove");
+ imageRemoveAction->setToolTip(i18n("Remove the current visible image"));
+
+ imageUsemapAction = new KAction(i18n("Edit Usemap..."),0,this,SLOT(imageUsemap()),
+ actionCollection(), "image_usemap");
+ imageUsemapAction->setToolTip(i18n("Edit the usemap tag of the current visible image"));
+
+ temp= new KAction(i18n("Show &HTML"),0,this,SLOT(mapShowHTML()),
+ actionCollection(), "map_showhtml");
+
+
+ // Selection Tool
+ arrowAction=new KRadioAction(i18n("&Selection"), "arrow",
+ 0,this,SLOT (slotDrawArrow()),
+ actionCollection(), "tool_arrow");
+ QMimeSourceFactory::defaultFactory()->setPixmap( "arrowimage", SmallIcon("arrow") );
+ arrowAction->setWhatsThis(i18n("<h3>Selection</h3>"
+ "Click this to select areas."));
+ arrowAction->setExclusiveGroup("drawing");
+ arrowAction->setChecked(true);
+
+ // Circle
+ circleAction=new KRadioAction(i18n("&Circle"), "circle",
+ 0,this,SLOT (slotDrawCircle()),
+ actionCollection(), "tool_circle");
+ QMimeSourceFactory::defaultFactory()->setPixmap( "circleimage", SmallIcon("drawcircle") );
+ circleAction->setWhatsThis(i18n("<h3>Circle</h3>"
+ "Click this to start drawing a circle."));
+ circleAction->setExclusiveGroup("drawing");
+
+ // Rectangle
+ rectangleAction=new KRadioAction(i18n("&Rectangle"), "rectangle",
+ 0,this,SLOT (slotDrawRectangle()),
+ actionCollection(), "tool_rectangle");
+ QMimeSourceFactory::defaultFactory()->setPixmap( "rectangleimage", SmallIcon("drawrectangle") );
+ rectangleAction->setWhatsThis(i18n("<h3>Rectangle</h3>"
+ "Click this to start drawing a rectangle."));
+ rectangleAction->setExclusiveGroup("drawing");
+
+ // Polygon
+ polygonAction=new KRadioAction(i18n("&Polygon"), "polygon",
+ 0,this,SLOT (slotDrawPolygon()),
+ actionCollection(), "tool_polygon");
+ QMimeSourceFactory::defaultFactory()->setPixmap( "polygonimage", SmallIcon("drawpolygon") );
+ polygonAction->setWhatsThis(i18n("<h3>Polygon</h3>"
+ "Click this to start drawing a polygon."));
+ polygonAction->setExclusiveGroup("drawing");
+
+ // Freehand
+ freehandAction=new KRadioAction(i18n("&Freehand Polygon"), "freehand",
+ 0,this,SLOT (slotDrawFreehand()),
+ actionCollection(), "tool_freehand");
+ QMimeSourceFactory::defaultFactory()->setPixmap( "freehandimage", SmallIcon("freehand") );
+ freehandAction->setWhatsThis(i18n("<h3>Freehandpolygon</h3>"
+ "Click this to start drawing a freehand polygon."));
+ freehandAction->setExclusiveGroup("drawing");
+
+ // Add Point
+ addPointAction=new KRadioAction(i18n("&Add Point"), "addpoint",
+ 0,this,SLOT (slotDrawAddPoint()),
+ actionCollection(), "tool_addpoint");
+ QMimeSourceFactory::defaultFactory()->setPixmap( "addpointimage", SmallIcon("addpoint") );
+ addPointAction->setWhatsThis(i18n("<h3>Add Point</h3>"
+ "Click this to add points to a polygon."));
+ addPointAction->setExclusiveGroup("drawing");
+
+ // Remove Point
+ removePointAction=new KRadioAction(i18n("&Remove Point"), "removepoint",
+ 0,this,SLOT (slotDrawRemovePoint()),
+ actionCollection(), "tool_removepoint");
+ QMimeSourceFactory::defaultFactory()->setPixmap( "removepointimage", SmallIcon("removepoint") );
+ removePointAction->setWhatsThis(i18n("<h3>Remove Point</h3>"
+ "Click this to remove points from a polygon."));
+ removePointAction->setExclusiveGroup("drawing");
+
+#if KDE_VERSION < 300
+ KAction *cancelAction =
+#endif
+ new KAction(i18n("Cancel Drawing"), Key_Escape, this, SLOT( slotCancelDrawing() ),
+ actionCollection(), "canceldrawing" );
+
+ moveLeftAction = new KAction(i18n("Move Left"), Key_Left, this, SLOT( slotMoveLeft() ),
+ actionCollection() , "moveleft" );
+
+ moveRightAction = new KAction(i18n("Move Right"), Key_Right, this, SLOT( slotMoveRight() ),
+ actionCollection() , "moveright" );
+
+ moveUpAction = new KAction(i18n("Move Up"), Key_Up, this, SLOT( slotMoveUp() ),
+ actionCollection() , "moveup" );
+
+ moveDownAction = new KAction(i18n("Move Down"), Key_Down, this, SLOT( slotMoveDown() ),
+ actionCollection() , "movedown" );
+
+ increaseWidthAction = new KAction(i18n("Increase Width"), Key_Right + SHIFT, this, SLOT( slotIncreaseWidth() ),
+ actionCollection() , "increasewidth" );
+
+ decreaseWidthAction = new KAction(i18n("Decrease Width"), Key_Left + SHIFT, this, SLOT( slotDecreaseWidth() ),
+ actionCollection() , "decreasewidth" );
+
+ increaseHeightAction = new KAction(i18n("Increase Height"), Key_Up + SHIFT, this, SLOT( slotIncreaseHeight() ),
+ actionCollection() , "increaseheight" );
+
+ decreaseHeightAction = new KAction(i18n("Decrease Height"), Key_Down + SHIFT, this, SLOT( slotDecreaseHeight() ),
+ actionCollection() , "decreaseheight" );
+#if KDE_VERSION < 300
+ accel = new KAccel(widget());
+ cancelAction->plugAccel(accel, true);
+ moveLeftAction->plugAccel(accel, true);
+ moveRightAction->plugAccel(accel, true);
+ moveUpAction->plugAccel(accel, true);
+ moveDownAction->plugAccel(accel, true);
+ increaseWidthAction->plugAccel(accel, true);
+ decreaseWidthAction->plugAccel(accel, true);
+ increaseHeightAction->plugAccel(accel, true);
+ decreaseHeightAction->plugAccel(accel, true);
+#endif
+
+ toFrontAction = new KAction(i18n("Bring to Front"), 0 , this, SLOT( slotToFront() ),
+ actionCollection() , "tofront" );
+
+ toBackAction = new KAction(i18n("Send to Back"), 0 , this, SLOT( slotToBack() ),
+ actionCollection() , "toback" );
+
+ forwardOneAction = new KAction(i18n("Bring Forward One"), "raise" ,0, this, SLOT( slotForwardOne() ),
+ actionCollection() , "forwardone" );
+ backOneAction = new KAction(i18n("Send Back One"), "lower" ,0, this, SLOT( slotBackOne() ),
+ actionCollection() , "backone" );
+
+ forwardOneAction->plug(areaListView->upBtn);
+ backOneAction->plug(areaListView->downBtn);
+
+ connect( areaListView->upBtn, SIGNAL(pressed()), forwardOneAction, SLOT(activate()));
+ connect( areaListView->downBtn, SIGNAL(pressed()), backOneAction, SLOT(activate()));
+
+ new KAction( i18n("Configure KImageMapEditor..."), "configure", 0,
+ this, SLOT(slotShowPreferences()),
+ actionCollection(), "configure_kimagemapeditor" );
+
+ if (areaDock) {
+ configureShowAreaListAction = new KToggleAction( i18n("Show Area List"), 0L, 0,
+ this, SLOT(configureShowAreaList()),
+ actionCollection(), "configure_show_arealist" );
+
+ configureShowMapListAction = new KToggleAction( i18n("Show Map List"), 0L, 0,
+ this, SLOT(configureShowMapList()),
+ actionCollection(), "configure_show_maplist" );
+
+ configureShowImageListAction = new KToggleAction( i18n("Show Image List"), 0L, 0,
+ this, SLOT(configureShowImageList()),
+ actionCollection(), "configure_show_imagelist" );
+#if KDE_IS_VERSION(3,2,90)
+ configureShowAreaListAction->setCheckedState(i18n("Hide Area List"));
+ configureShowMapListAction->setCheckedState(i18n("Hide Map List"));
+ configureShowImageListAction->setCheckedState(i18n("Hide Image List"));
+#endif
+ }
+
+ updateActionAccess();
+}
+
+void KImageMapEditor::setupStatusBar()
+{
+
+// We can't do this with a KPart !
+// widget()->statusBar()->insertItem(i18n(" Cursor")+" : x: 0 ,y: 0",STATUS_CURSOR);
+// widget()->statusBar()->insertItem(i18n(" Selection")+" : - ",STATUS_SELECTION);
+ emit setStatusBarText( i18n(" Selection: - Cursor: x: 0, y: 0 "));
+}
+
+void KImageMapEditor::slotShowPreferences()
+{
+ PreferencesDialog *dialog = new PreferencesDialog(widget(),config());
+ connect(dialog, SIGNAL(applyClicked()), this, SLOT(slotConfigChanged()));
+ dialog->exec();
+ delete dialog;
+}
+
+
+void KImageMapEditor::showPopupMenu(const QPoint & pos, const QString & name)
+{
+ QPopupMenu* pop = static_cast<QPopupMenu *>(factory()->container(name, this));
+
+ if (!pop) {
+ kdWarning() << QString("KImageMapEditorPart: Missing XML definition for %1\n").arg(name) << endl;
+ return;
+ }
+
+ pop->popup(pos);
+}
+
+void KImageMapEditor::slotShowMainPopupMenu(const QPoint & pos)
+{
+ showPopupMenu(pos,"popup_main");
+}
+
+void KImageMapEditor::slotShowMapPopupMenu(QListViewItem* item,const QPoint & pos)
+{
+ if (isReadWrite()) {
+ mapDeleteAction->setEnabled(item);
+ mapNameAction->setEnabled(item);
+ mapDefaultAreaAction->setEnabled(item);
+ }
+
+ if (item)
+ mapsListView->selectMap(item);
+
+ showPopupMenu(pos,"popup_map");
+}
+
+void KImageMapEditor::slotShowImagePopupMenu(QListViewItem* item,const QPoint & pos)
+{
+ imageRemoveAction->setEnabled(item);
+ imageUsemapAction->setEnabled(item);
+
+ if (item)
+ imagesListView->setSelected(item,true);
+
+ showPopupMenu(pos,"popup_image");
+}
+
+void KImageMapEditor::slotShowPopupMenu(QListViewItem* item,const QPoint & p)
+{
+ if (!item)
+ return;
+
+ if (!item->isSelected())
+ {
+ deselectAll();
+ select(item);
+ }
+
+ slotShowMainPopupMenu(p);
+}
+
+void KImageMapEditor::updateStatusBar()
+{
+ emit setStatusBarText(selectionStatusText+" "+cursorStatusText);
+}
+
+void KImageMapEditor::slotChangeStatusCoords(int x,int y)
+{
+// statusBar()->changeItem(QString(" Cursor : x: %1 ,y: %2 ").arg(x).arg(y),STATUS_CURSOR);
+ cursorStatusText = i18n(" Cursor: x: %1, y: %2 ").arg(x).arg(y);
+ updateStatusBar();
+}
+
+void KImageMapEditor::slotUpdateSelectionCoords() {
+ if (selected()->count()>0) {
+ QRect r=selected()->rect();
+// statusBar()->changeItem(
+ selectionStatusText = i18n(" Selection: x: %1, y: %2, w: %3, h: %4 ").arg(r.left()).arg(r.top()).arg(r.width()).arg(r.height());
+
+// ,STATUS_SELECTION);
+ kapp->processEvents();
+ } else
+ selectionStatusText = i18n(" Selection: - ");
+ //statusBar()->changeItem(" Selection : - ",STATUS_SELECTION);
+
+ updateStatusBar();
+}
+
+void KImageMapEditor::slotUpdateSelectionCoords( const QRect & r )
+{
+ selectionStatusText = i18n(" Selection: x: %1, y: %2, w: %3, h: %4 ").arg(r.left()).arg(r.top()).arg(r.width()).arg(r.height());
+ updateStatusBar();
+ kapp->processEvents();
+}
+
+KApplication* KImageMapEditor::app() const
+{
+ return kapp;
+}
+
+
+void KImageMapEditor::drawToCenter(QPainter* p, const QString & str, int y, int width) {
+ int xmid = width / 2;
+
+ QFontMetrics fm = p->fontMetrics();
+ QRect strBounds = fm.boundingRect(str);
+
+ p->drawText(xmid-(strBounds.width()/2),y,str);
+}
+
+
+QImage KImageMapEditor::getBackgroundImage() {
+
+ // Lazy initialisation
+ if ( _backgroundImage.isNull() ) {
+
+
+// QString filename = QString("dropimage_")+KGlobal::locale()->language()+".png";
+// QString path = QString::null; //KGlobal::dirs()->findResourceDir( "data", "kimagemapeditor/"+filename ) + "kimagemapeditor/"+filename;
+// kdDebug() << "getBackgroundPic : loaded image : " << path << endl;
+
+// if ( ! QFileInfo(path).exists() ) {
+ int width = 400;
+ int height = 400;
+ int border = 20;
+ int fontSize = 58;
+
+ QPixmap pix(width,height);
+ pix.fill(QColor(74,76,74));
+ QPainter p(&pix);
+
+ QFont font;
+ font.setFamily("Sans");
+ font.setPixelSize(fontSize);
+ font.setBold(true);
+ p.setFont( font );
+
+ p.setRasterOp(Qt::CopyROP);
+ p.setPen(QPen(QColor(112,114,112),1));
+
+ // The translated string must be divided into
+ // parts with about the same size that fit to the image
+ QString str = i18n("Drop an image or HTML file");
+ QStringList strList = QStringList::split(" ",str);
+
+ // Get the string parts
+ QString tmp;
+ QStringList outputStrList;
+ QFontMetrics fm = p.fontMetrics();
+
+ for ( QStringList::Iterator it = strList.begin(); it != strList.end(); ++it ) {
+ QString tmp2 = tmp + *it;
+
+ if (fm.boundingRect(tmp2).width() > width-border) {
+ outputStrList.append(tmp);
+ tmp = *it + " ";
+ }
+ else
+ tmp = tmp2 + " ";
+ }
+
+ // Last one was forgotten so add it.
+ outputStrList.append(tmp);
+
+ // Try to adjust the text vertically centered
+ int step = myround(float(height) / (outputStrList.size()+1));
+ int y = step;
+
+ for ( QStringList::Iterator it = outputStrList.begin(); it != outputStrList.end(); ++it ) {
+ drawToCenter(&p, *it, y, pix.width());
+ y += step;
+ }
+
+ p.end();
+
+ _backgroundImage = pix.convertToImage();
+ }
+
+
+ return _backgroundImage;
+
+/*
+ QFontDatabase fdb;
+ QStringList families = fdb.families();
+ for ( QStringList::Iterator f = families.begin(); f != families.end(); ++f ) {
+ QString family = *f;
+ qDebug( family );
+ QStringList styles = fdb.styles( family );
+ for ( QStringList::Iterator s = styles.begin(); s != styles.end(); ++s ) {
+ QString style = *s;
+ QString dstyle = "\t" + style + " (";
+ QValueList<int> smoothies = fdb.smoothSizes( family, style );
+ for ( QValueList<int>::Iterator points = smoothies.begin();
+ points != smoothies.end(); ++points ) {
+ dstyle += QString::number( *points ) + " ";
+ }
+ dstyle = dstyle.left( dstyle.length() - 1 ) + ")";
+ qDebug( dstyle );
+ }
+ }
+
+
+ path = KGlobal::dirs()->saveLocation( "data", "kimagemapeditor/" ) +filename;
+ kdDebug() << "getBackgroundPic : save new image to : " << path << endl;
+ pix.save(path,"PNG",100);
+ }
+
+ if ( ! QFileInfo(path).exists() ) {
+ kdError() << "Couldn't find needed " << filename << " file in "
+ "the data directory of KImageMapEditor.\n"
+ "Perhaps you have forgotten to do a make install !" << endl;
+ exit(1);
+ }
+*/
+}
+
+
+void KImageMapEditor::addArea(Area* area) {
+ if (!area) return;
+
+ // Perhaps we've got a selection of areas
+ // so test it and add all areas of the selection
+ // nested selections are possible but doesn't exist
+ AreaSelection *selection=0L;
+ if ( (selection = dynamic_cast <AreaSelection*> ( area ) ) )
+ {
+ AreaList list = selection->getAreaList();
+
+ for (Area* a = list.first(); a != 0L; a = list.next() )
+ {
+ areas->prepend(a);
+ a->setListViewItem(new QListViewItem(areaListView->listView,a->attribute("href")));
+ a->listViewItem()->setPixmap(1,makeListViewPix(*a));
+ }
+ }
+ else
+ {
+ areas->prepend(area);
+ area->setListViewItem(new QListViewItem(areaListView->listView,area->attribute("href")));
+ area->listViewItem()->setPixmap(1,makeListViewPix(*area));
+ }
+
+ setModified(true);
+
+}
+
+void KImageMapEditor::addAreaAndEdit(Area* s)
+{
+ areas->prepend(s);
+ s->setListViewItem(new QListViewItem(areaListView->listView,s->attribute("href")));
+ s->listViewItem()->setPixmap(1,makeListViewPix(*s));
+ deselectAll();
+ select(s);
+ if (!showTagEditor(selected())) {
+ // If the user has pressed cancel
+ // he undos the creation
+ commandHistory()->undo();
+ }
+}
+
+void KImageMapEditor::deleteArea( Area * area )
+{
+ if (!area) return;
+
+ // only for repaint reasons
+ QRect redrawRect = area->selectionRect();
+
+ // Perhaps we've got a selection of areas
+ // so test it and delete the whole selection
+ // nested selections are possible but doesn't exist
+ AreaSelection *selection=0L;
+ if ( (selection = dynamic_cast <AreaSelection*> ( area ) ) )
+ {
+ AreaList list = selection->getAreaList();
+
+ for (Area* a = list.first(); a != 0L; a = list.next() )
+ {
+ currentSelected->remove(a);
+ areas->remove( a );
+ a->deleteListViewItem();
+ }
+ }
+ else
+ {
+ deselect( area );
+ areas->remove( area );
+ area->deleteListViewItem();
+ }
+
+ drawZone->repaintRect(redrawRect);
+
+
+ // Only to disable cut and copy actions
+ if (areas->count()==0)
+ deselectAll();
+
+ setModified(true);
+}
+
+void KImageMapEditor::deleteSelected() {
+
+ Area *a;
+ AreaList list=currentSelected->getAreaList();
+
+ for ( a=list.first(); a != 0; a=list.next() ) {
+ currentSelected->remove( a );
+ areas->remove( a );
+ delete a->listViewItem();
+ }
+
+
+ drawZone->repaintArea( *currentSelected );
+ // Only to disable cut and copy actions
+ if (areas->count()==0)
+ deselectAll();
+
+ setModified(true);
+}
+
+void KImageMapEditor::deleteAllAreas()
+{
+ for (Area* a=areas->first();a!=0L;)
+ {
+ deselect( a );
+ areas->remove( a );
+ a->deleteListViewItem();
+ a=areas->first(); // because the current is deleted
+ }
+
+ drawZone->viewport()->repaint();
+
+}
+
+void KImageMapEditor::updateAllAreas()
+{
+// kdDebug() << "KImageMapEditor::updateAllAreas" << endl;
+ for (Area* a=areas->first();a!=0L;a=areas->next()) {
+ a->listViewItem()->setPixmap(1,makeListViewPix(*a));
+ }
+ drawZone->viewport()->repaint();
+}
+
+void KImageMapEditor::updateSelection() const {
+ areaListView->listView->triggerUpdate();
+}
+
+AreaSelection* KImageMapEditor::selected() const {
+ return currentSelected;
+}
+
+void KImageMapEditor::select(Area* a)
+{
+ if (!a) return;
+
+ currentSelected->add(a);
+ updateActionAccess();
+ slotUpdateSelectionCoords();
+// drawZone->repaintArea( *a);
+
+}
+
+void KImageMapEditor::selectWithoutUpdate(Area* a)
+{
+ if (!a) return;
+ currentSelected->add(a);
+}
+
+void KImageMapEditor::slotSelectionChanged()
+{
+ AreaListIterator it = areaList();
+ AreaList list = currentSelected->getAreaList();
+
+ for ( ; it.current() != 0L; ++it)
+ {
+ if ( it.current()->listViewItem()->isSelected() != (list.containsRef(it.current()) > 0) )
+ {
+ it.current()->listViewItem()->isSelected()
+ ? select( it.current() )
+ : deselect( it.current() );
+
+ drawZone->repaintArea( *it.current());
+ }
+ }
+
+}
+
+void KImageMapEditor::select( QListViewItem* item)
+{
+
+ AreaListIterator it = areaList();
+
+ for ( ; it.current() != 0L; ++it)
+ {
+ if (it.current()->listViewItem() == item )
+ {
+ select( it.current() );
+ drawZone->repaintArea( *it.current());
+ }
+ }
+
+
+}
+
+AreaListIterator KImageMapEditor::areaList() const {
+ AreaListIterator it(*areas);
+ return it;
+}
+
+
+void KImageMapEditor::slotAreaChanged(Area *area)
+{
+ if (!area)
+ return;
+
+ setModified(true);
+
+ AreaSelection *selection=0L;
+ if ( (selection = dynamic_cast <AreaSelection*> ( area ) ) )
+ {
+ AreaListIterator it = selection->getAreaListIterator();
+
+ for ( ; it.current() != 0L; ++it )
+ {
+ if (it.current()->listViewItem()) {
+ it.current()->listViewItem()->setText(0,it.current()->attribute("href"));
+ it.current()->listViewItem()->setPixmap(1,makeListViewPix(*it.current()));
+ }
+ }
+
+ }
+ else
+ if (area->listViewItem()) {
+ area->listViewItem()->setText(0,area->attribute("href"));
+ area->listViewItem()->setPixmap(1,makeListViewPix(*area));
+ }
+
+ drawZone->repaintArea(*area);
+
+}
+
+void KImageMapEditor::deselect(Area* a)
+{
+ if (a) {
+ currentSelected->remove(a);
+// drawZone->repaintArea(*a);
+ updateActionAccess();
+ slotUpdateSelectionCoords();
+ }
+}
+
+void KImageMapEditor::deselectWithoutUpdate(Area* a)
+{
+ if (a) {
+ currentSelected->remove(a);
+ }
+}
+
+
+/**
+* Makes sure, that the actions cut, copy, delete and
+* show properties
+* can only be executed if sth. is selected.
+**/
+void KImageMapEditor::updateActionAccess()
+{
+ if (!isReadWrite())
+ return;
+
+ if ( 0 < selected()->count())
+ {
+ areaPropertiesAction->setEnabled(true);
+ deleteAction->setEnabled(true);
+ copyAction->setEnabled(true);
+ cutAction->setEnabled(true);
+ moveLeftAction->setEnabled(true);
+ moveRightAction->setEnabled(true);
+ moveUpAction->setEnabled(true);
+ moveDownAction->setEnabled(true);
+ toFrontAction->setEnabled(true);
+ toBackAction->setEnabled(true);
+
+ if ( (selected()->count() == 1) )
+ {
+ if (selected()->type()==Area::Polygon)
+ {
+ increaseWidthAction->setEnabled(false);
+ decreaseWidthAction->setEnabled(false);
+ increaseHeightAction->setEnabled(false);
+ decreaseHeightAction->setEnabled(false);
+ addPointAction->setEnabled(true);
+ removePointAction->setEnabled(true);
+ }
+ else
+ {
+ increaseWidthAction->setEnabled(true);
+ decreaseWidthAction->setEnabled(true);
+ increaseHeightAction->setEnabled(true);
+ decreaseHeightAction->setEnabled(true);
+ addPointAction->setEnabled(false);
+ removePointAction->setEnabled(false);
+ }
+
+ }
+ else
+ {
+ increaseWidthAction->setEnabled(false);
+ decreaseWidthAction->setEnabled(false);
+ increaseHeightAction->setEnabled(false);
+ decreaseHeightAction->setEnabled(false);
+ addPointAction->setEnabled(false);
+ removePointAction->setEnabled(false);
+ }
+
+ }
+ else
+ {
+ areaPropertiesAction->setEnabled(false);
+ deleteAction->setEnabled(false);
+ copyAction->setEnabled(false);
+ cutAction->setEnabled(false);
+ moveLeftAction->setEnabled(false);
+ moveRightAction->setEnabled(false);
+ moveUpAction->setEnabled(false);
+ moveDownAction->setEnabled(false);
+ increaseWidthAction->setEnabled(false);
+ decreaseWidthAction->setEnabled(false);
+ increaseHeightAction->setEnabled(false);
+ decreaseHeightAction->setEnabled(false);
+ toFrontAction->setEnabled(false);
+ toBackAction->setEnabled(false);
+ addPointAction->setEnabled(false);
+ removePointAction->setEnabled(false);
+
+ }
+
+ updateUpDownBtn();
+}
+
+void KImageMapEditor::updateUpDownBtn()
+{
+ if (!isReadWrite())
+ return;
+
+ AreaList list = currentSelected->getAreaList();
+
+ if (list.isEmpty() || (areas->count() < 2))
+ {
+ forwardOneAction->setEnabled(false);
+ areaListView->upBtn->setEnabled(false);
+ backOneAction->setEnabled(false);
+ areaListView->downBtn->setEnabled(false);
+ return;
+ }
+ // if the first Area is in the selection can't move up
+ if (list.find( areas->getFirst() ) == -1)
+ {
+ forwardOneAction->setEnabled(true);
+ areaListView->upBtn->setEnabled(true);
+ }
+ else {
+ forwardOneAction->setEnabled(false);
+ areaListView->upBtn->setEnabled(false);
+ }
+
+ drawZone->repaintArea(*currentSelected);
+
+ // if the last Area is in the selection can't move down
+ if (list.find( areas->getLast() ) == -1)
+ {
+ backOneAction->setEnabled(true);
+ areaListView->downBtn->setEnabled(true);
+ }
+ else {
+ backOneAction->setEnabled(false);
+ areaListView->downBtn->setEnabled(false);
+ }
+
+}
+
+void KImageMapEditor::deselectAll()
+{
+ QRect redrawRect= currentSelected->selectionRect();
+ currentSelected->reset();
+ drawZone->repaintRect(redrawRect);
+ updateActionAccess();
+}
+
+Area* KImageMapEditor::onArea(const QPoint & p) const {
+ for (Area* s=areas->first();s!=0L;s=areas->next()) {
+ if (s->contains(p))
+ return s;
+ }
+ return 0L;
+}
+
+
+int KImageMapEditor::showTagEditor(Area *a) {
+ if (!a) return 0;
+ drawZone->repaintArea(*a);
+
+ AreaDialog *dialog= new AreaDialog(this,a);
+ connect (dialog, SIGNAL(areaChanged(Area*)), this, SLOT(slotAreaChanged(Area*)));
+
+ int result = dialog->exec();
+
+ return result;
+
+
+}
+
+int KImageMapEditor::showTagEditor(QListViewItem *item) {
+ if (!item) return 0;
+ for (Area* a=areas->first();a!=0L;a=areas->next()) {
+ if (a->listViewItem()==item) {
+ return showTagEditor(a);
+ }
+ }
+ return 0;
+}
+
+int KImageMapEditor::showTagEditor() {
+ return showTagEditor(selected());
+}
+
+
+QString KImageMapEditor::getHTMLImageMap() const {
+ QString retStr;
+ retStr+="<map "+QString("name=\"")+_mapName+"\">\n";
+
+ for (Area* a=areas->first();a!=0L;a=areas->next()) {
+ retStr+=" "+a->getHTMLCode()+"\n";
+ }
+
+ if (defaultArea && defaultArea->finished())
+ retStr+=" "+defaultArea->getHTMLCode()+"\n";
+
+ retStr+="</map>";
+ return retStr;
+}
+
+QPixmap KImageMapEditor::makeListViewPix(Area & a)
+{
+ QPixmap pix=a.cutOut(drawZone->picture());
+
+ double shrinkFactor=1;
+
+ // picture fits into max row height ?
+ if (maxAreaPreviewHeight < pix.height())
+ shrinkFactor = ( (double) maxAreaPreviewHeight / pix.height() );
+
+ QPixmap pix2((int)(pix.width()*shrinkFactor), (int)(pix.height()*shrinkFactor));
+
+ // Give all pixels a defined color
+ pix2.fill(Qt::white);
+
+ QPainter p(&pix2);
+
+ p.scale(shrinkFactor,shrinkFactor);
+ p.drawPixmap(0,0,pix);
+
+ return pix2;
+}
+
+void KImageMapEditor::setMapName(const QString & s) {
+ mapsListView->changeMapName(_mapName, s);
+ _mapName=s;
+ currentMapElement->mapTag->name = s;
+}
+
+
+void KImageMapEditor::setPicture(const KURL & url) {
+ _imageUrl=url;
+ if (QFileInfo(url.path()).exists()) {
+ QImage img(url.path());
+
+ if (!img.isNull()) {
+ setPicture(img);
+ imageRemoveAction->setEnabled(true);
+ imageUsemapAction->setEnabled(true);
+ }
+ else
+ kdError() << QString("The image %1 could not be opened.").arg(url.path()) << endl;
+ }
+ else
+ kdError() << QString("The image %1 does not exist.").arg(url.path()) << endl;
+}
+
+void KImageMapEditor::setPicture(const QImage & pix) {
+ drawZone->setPicture(pix);
+ updateAllAreas();
+}
+
+
+void KImageMapEditor::slotDrawArrow() {
+ _currentToolType=KImageMapEditor::Selection;
+
+}
+
+void KImageMapEditor::slotDrawCircle() {
+ _currentToolType=KImageMapEditor::Circle;
+
+}
+
+void KImageMapEditor::slotDrawRectangle() {
+ _currentToolType=KImageMapEditor::Rectangle;
+
+}
+
+void KImageMapEditor::slotDrawPolygon() {
+ _currentToolType=KImageMapEditor::Polygon;
+}
+
+void KImageMapEditor::slotDrawFreehand() {
+ _currentToolType=KImageMapEditor::Freehand;
+}
+
+void KImageMapEditor::slotDrawAddPoint() {
+ _currentToolType=KImageMapEditor::AddPoint;
+}
+
+void KImageMapEditor::slotDrawRemovePoint() {
+ _currentToolType=KImageMapEditor::RemovePoint;
+}
+
+
+void KImageMapEditor::slotZoom() {
+
+ int i=zoomAction->currentItem();
+ switch (i) {
+ case 0 : drawZone->setZoom(0.25);break;
+ case 1 : drawZone->setZoom(0.5);break;
+ case 2 : drawZone->setZoom(1);break;
+ case 3 : drawZone->setZoom(1.5);break;
+ case 4 : drawZone->setZoom(2.0);break;
+ case 5 : drawZone->setZoom(2.5);break;
+ case 6 : drawZone->setZoom(3);break;
+ case 7 : drawZone->setZoom(5);break;
+ case 8 : drawZone->setZoom(7.5);break;
+ case 9 : drawZone->setZoom(10);break;
+ }
+ if (i<10)
+ zoomInAction->setEnabled(true);
+ else
+ zoomInAction->setEnabled(false);
+
+ if (i>0)
+ zoomOutAction->setEnabled(true);
+ else
+ zoomOutAction->setEnabled(false);
+}
+
+void KImageMapEditor::slotZoomIn() {
+ if (zoomAction->currentItem()==(int)(zoomAction->items().count()-1))
+ return;
+
+ zoomAction->setCurrentItem(zoomAction->currentItem()+1);
+ slotZoom();
+}
+
+void KImageMapEditor::slotZoomOut() {
+ if (zoomAction->currentItem()==0)
+ return;
+
+ zoomAction->setCurrentItem(zoomAction->currentItem()-1);
+ slotZoom();
+}
+
+void KImageMapEditor::mapDefaultArea()
+{
+ if (defaultArea)
+ showTagEditor(defaultArea);
+ else {
+ defaultArea= new DefaultArea();
+ showTagEditor(defaultArea);
+ }
+
+}
+
+void KImageMapEditor::mapEditName()
+{
+ bool ok=false;
+#if KDE_IS_VERSION(3, 1, 90)
+ QString input = KInputDialog::getText(i18n("Enter Map Name"),
+ i18n("Enter the name of the map:"),
+ _mapName,&ok,widget());
+#else
+ QString input = KLineEditDlg::getText(i18n("Enter Map Name"),
+ i18n("Enter the name of the map:"),
+ _mapName,&ok,widget());
+#endif
+ if (ok) {
+ if (input != _mapName) {
+ if (mapsListView->nameAlreadyExists(input))
+ KMessageBox::sorry(this->widget(), i18n("The name <em>%1</em> already exists.").arg(input));
+ else {
+ setMapName(input);
+ }
+ }
+ }
+}
+
+void KImageMapEditor::mapShowHTML()
+{
+ KDialogBase *dialog= new KDialogBase(widget(),QString::null,true,i18n("HTML Code of Map"),KDialogBase::Ok);
+ QMultiLineEdit *edit = new QMultiLineEdit(dialog);
+
+ edit->setText(getHtmlCode());
+ edit->setReadOnly(true);
+ edit->setWordWrap(QTextEdit::NoWrap);
+ dialog->setMainWidget(edit);
+// dialog->resize(dialog->calculateSize(edit->maxLineWidth(),edit->numLines()*));
+// dialog->adjustSize();
+ dialog->resize(600,400);
+ dialog->exec();
+}
+
+void KImageMapEditor::openFile(const KURL & url) {
+ if ( ! url.isEmpty()) {
+ QString ext=QFileInfo(url.path()).extension().lower();
+
+ if (ext=="png" || ext=="jpg" || ext=="jpeg" || ext=="gif" ||
+ ext=="bmp" || ext=="xbm" || ext=="xpm" || ext=="mng" || ext=="pnm")
+ addImage(url);
+ else
+ openURL(url);
+ }
+}
+
+bool KImageMapEditor::openURL(const KURL & url) {
+ // If a local file does not exist
+ // we start with an empty file, so
+ // that we can return true here.
+ // For non local files, we cannot check
+ // the existance
+ if (url.isLocalFile() &&
+ ! QFile::exists(url.path()))
+ return true;
+ return KParts::ReadOnlyPart::openURL(url);
+}
+
+void KImageMapEditor::fileOpen() {
+
+ QString fileName = KFileDialog::getOpenFileName(QString::null,
+ i18n("*.png *.jpg *.jpeg *.gif *.htm *.html|Web File\n"
+ "*.png *.jpg *.jpeg *.gif *.bmp *.xbm *.xpm *.pnm *.mng|Images\n"
+ "*.htm *.html|HTML Files\n"
+ "*.png|PNG Images\n*.jpg *.jpeg|JPEG Images\n*.gif|GIF-Images\n*|All Files"),
+ widget(),i18n("Choose File to Open"));
+
+ openFile(KURL( fileName ));
+}
+
+
+
+void KImageMapEditor::fileClose()
+{
+ if (! closeURL())
+ return;
+
+
+ setPicture(getBackgroundImage());
+ recentFilesAction->setCurrentItem(-1);
+ setModified(false);
+}
+
+void KImageMapEditor::fileSave()
+{
+ // if we aren't read-write, return immediately
+ if ( ! isReadWrite() )
+ return;
+
+ if (url().isEmpty()) {
+ fileSaveAs();
+ }
+ else {
+ saveFile();
+ setModified(false);
+ }
+
+
+}
+
+void KImageMapEditor::fileSaveAs() {
+
+ KURL url = KFileDialog::getSaveURL(0L,"*.htm *.html|" + i18n( "HTML File" ) +
+ "\n*.txt|" + i18n( "Text File" ) + "\n*|" + i18n( "All Files" ),widget());
+ if (url.isEmpty() || !url.isValid()) {
+ return;
+ }
+
+
+ QFileInfo fileInfo(url.path());
+
+ if ( fileInfo.exists() )
+ {
+ if (KMessageBox::warningContinueCancel(widget(),
+ i18n("<qt>The file <em>%1</em> already exists.<br>Do you want to overwrite it?</qt>").arg(fileInfo.fileName()),
+ i18n("Overwrite File?"), i18n("Overwrite"))==KMessageBox::Cancel)
+ return;
+
+ if(!fileInfo.isWritable()) {
+ KMessageBox::sorry(widget(), i18n("<qt>You do not have write permission for the file <em>%1</em>.</qt>").arg(fileInfo.fileName()));
+ return;
+ }
+ }
+
+
+ saveAs(url);
+ recentFilesAction->addURL(url);
+
+}
+
+
+bool KImageMapEditor::openFile()
+{
+ QFileInfo fileInfo(url().path());
+
+ if ( !fileInfo.exists() )
+ {
+ KMessageBox::information(widget(),
+ i18n("<qt>The file <b>%1</b> does not exist.</qt>").arg(fileInfo.fileName()),
+ i18n("File Does Not Exist"));
+ return false;
+ }
+
+ openHTMLFile(url());
+
+ drawZone->viewport()->repaint();
+ recentFilesAction->addURL(url());
+ setModified(false);
+ backupFileCreated = false;
+ return true;
+}
+
+/**
+ * This methods supposes that the given QTextStream s has just read
+ * the &lt; of a tag. It now reads all attributes of the tag until a &gt;
+ * The tagname itself is also read and stored as a <em>tagname</em>
+ * attribute. After parsing the whole tag it returns a QDict<QString>
+ * with all attributes and their values. It stores the whole read text in the
+ * parameter readText.
+ */
+QDict<QString> KImageMapEditor::getTagAttributes(QTextStream & s, QString & readText)
+{
+ QDict<QString> dict(17,false);
+ // the "<" is already read
+ QChar w;
+ QString attr,value;
+
+ readText = QString::null;
+
+ // get the tagname
+ while (!s.atEnd() && w!=" ") {
+ s >> w;
+ readText.append(w);
+ if (w==" " || w==">") {
+ dict.insert("tagname",new QString(value));
+ break;
+ }
+ value+=w;
+ }
+
+
+ // do we have a comment ?
+ // read the comment and return
+ if (value.right(3)=="-->")
+ return dict;
+
+ if (value.startsWith("!--")) {
+ while (!s.atEnd()) {
+ s >> w;
+ readText.append(w);
+
+ if (w=="-") {
+ s >> w;
+ readText.append(w);
+ if (w=="-") {
+ s >> w;
+ readText.append(w);
+ if (w==">")
+ return dict;
+ }
+ }
+ }
+ }
+
+ bool attrRead=true; // currently reading an attribute ?
+ bool equalSign=false; // an equalsign was read?
+ bool valueRead=false; // currently reading a value ?
+ QChar quotation='\0'; // currently reading a value with quotation marks ?
+ bool php=false; // currently reading a php script
+ attr=QString::null;
+ value=QString::null;
+
+ //get the other attributes
+ while (!s.atEnd() && w!=">")
+ {
+ s >> w;
+ readText.append(w);
+
+ // End of PHP Script ?
+ if (php && (w=="?") )
+ {
+ s >> w;
+ readText.append(w);
+
+ if (valueRead)
+ value+=w;
+
+ if (w==">")
+ {
+ php = false;
+ s >> w;
+ readText.append(w);
+ }
+ }
+
+ // Wrong syntax or PHP-Skript !
+ if (!php && (w=="<"))
+ {
+ if (valueRead)
+ value+=w;
+ s >> w;
+ readText.append(w);
+ if (valueRead)
+ value+=w;
+
+ if (w=="?")
+ {
+ php = true;
+ }
+ } else
+ // finished ?
+ if (w==">") {
+ if (valueRead)
+ dict.insert(attr,new QString(value));
+ return dict;
+ } else
+ // currently reading an attribute ?
+ if (attrRead) {
+ // if there is a whitespace the attributename has finished
+ // possibly there isn't any value e.g. noshade
+ if (w==" ")
+ attrRead=false;
+ else
+ // an equal sign signals that the value follows
+ if (w=="=") {
+ attrRead=false;
+ equalSign=true;
+ } else
+ attr+=w;
+ } else
+ // an equal sign was read ? delete every whitespace
+ if (equalSign) {
+ if (w!=" ") {
+ equalSign=false;
+ valueRead=true;
+ if (w=="\"" || w=="'")
+ quotation=w;
+ }
+ } else
+ // currently reading the value
+ if (valueRead) {
+ // if php, read without regarding anything
+ if (php)
+ value+=w;
+ // if value within quotation marks is read
+ // only stop when another quotationmark is found
+ else
+ if (quotation != '\0') {
+ if (quotation!=w) {
+ value+=w;
+ } else {
+ quotation='\0';
+ valueRead=false;
+ dict.insert(attr,new QString(value));
+ attr = value = QString::null;
+
+ }
+ } else
+ // a whitespace indicates that the value has finished
+ if (w==" ") {
+ valueRead=false;
+ dict.insert(attr,new QString(value));
+ attr = value = QString::null;
+ }
+ } else {
+ if (w!=" ") {
+ attrRead=true;
+ attr+=w;
+ }
+ }
+ }
+
+ return dict;
+
+}
+
+
+bool KImageMapEditor::openHTMLFile(const KURL & url, const QString & mapName, const QString & imagePath)
+{
+ QFile f(url.path());
+ if ( !f.exists () )
+ return false;
+ f.open(IO_ReadOnly);
+ QTextStream s(&f);
+ QString str;
+ QChar w;
+ QDict<QString> *attr=0L;
+ QPtrList<ImageTag> *images= new QPtrList<ImageTag>;
+ MapTag *map=0L;
+ QPtrList<MapTag> *maps = new QPtrList<MapTag>;
+
+ _htmlContent.clear();
+ currentMapElement = 0L;
+
+ QString temp;
+ QString origcode;
+
+ bool readMap=false;
+
+ while (!s.atEnd()) {
+
+ s >> w;
+ if (w=="<")
+ {
+ if (!readMap && !origcode.isEmpty()) {
+ _htmlContent.append( new HtmlElement(origcode));
+ origcode = QString::null;
+ }
+
+ origcode.append("<");
+ attr=new QDict<QString>(getTagAttributes(s,temp));
+ origcode.append(temp);
+
+ if (attr->find("tagname")) {
+
+ if (attr->find("tagname")->lower()=="img") {
+ HtmlImgElement *el = new HtmlImgElement(origcode);
+ el->imgTag = static_cast<ImageTag*>(attr);
+ images->append(el->imgTag);
+ _htmlContent.append(el);
+
+ origcode = QString::null;
+ } else
+ if (attr->find("tagname")->lower()=="map") {
+ map = new MapTag();
+ map->name=(*attr->find("name"));
+ readMap=true;
+ } else
+ if (attr->find("tagname")->lower()=="/map") {
+ readMap=false;
+ maps->append(map);
+ HtmlMapElement *el = new HtmlMapElement(origcode);
+ el->mapTag = map;
+ _htmlContent.append(el);
+
+ origcode = QString::null;
+ } else
+ if (readMap) {
+ if (attr->find("tagname")->lower()=="area") {
+ map->prepend(attr);
+ }
+ } else {
+ _htmlContent.append(new HtmlElement(origcode));
+ origcode = QString::null;
+ }
+
+ }
+ } // w != "<"
+ else {
+ origcode.append(w);
+ }
+ }
+
+ if (!origcode.isEmpty()) {
+ _htmlContent.append(new HtmlElement(origcode));
+ }
+
+ f.close();
+
+ KURL imageUrl;
+ map = 0L;
+
+
+
+ // If there is a preselection of map and image
+ // don't let the user choose something
+ if (imagePath.isNull() || mapName.isNull()) {
+ // If we have more than on map or more than one image
+ // Let the user choose, otherwise take the only ones
+ if (maps->count() == 1) {
+ map = maps->first();
+ }
+
+ if (images->count() == 1) {
+ if (images->first()) {
+ ImageTag* imgTag = images->first();
+ QString *src = imgTag->find("src");
+ if (src)
+ imageUrl = KURL(url,*src);
+ }
+ }
+
+ // If there is only one map and more than one image
+ // try to find out the image with the according usemap tag
+ if (maps->count() == 1 && images->count() > 1) {
+ ImageTag* imageTag;
+ for ( imageTag = images->first(); imageTag; imageTag = images->next() )
+ {
+ QString *usemap = imageTag->find("usemap");
+ if (usemap) {
+ // Remove the #
+ QString usemapName = usemap->right(usemap->length()-1);
+ if (usemapName == map->name) {
+ QString *src = imageTag->find("src");
+ if (src)
+ imageUrl = KURL(url,*src);
+ }
+ }
+ }
+ }
+
+
+ // If there are more than one map or there wasn't
+ // found a fitting image and there is something to choose
+ // let the user choose
+ if (maps->count() >1 || (imageUrl.isEmpty() && images->count() > 1))
+ {
+ ImageMapChooseDialog dialog(widget(),maps,images,url);
+ dialog.exec();
+ map=dialog.currentMap;
+ imageUrl=dialog.pixUrl;
+ }
+ }
+ else
+ imageUrl = imagePath;
+
+ imagesListView->clear();
+ imagesListView->setBaseUrl(url);
+ imagesListView->addImages(images);
+
+ mapsListView->clear();
+ mapsListView->addMaps(maps);
+
+
+ setMapActionsEnabled(false);
+
+ if (map) {
+ mapsListView->selectMap(map->name);
+ }
+ else if ( ! mapName.isNull()) {
+ mapsListView->selectMap(mapName);
+ } else {
+ if (tabWidget)
+ tabWidget->showPage(mapsListView);
+ }
+
+ if (!imageUrl.isEmpty()) {
+ setPicture(imageUrl);
+ } else {
+ setPicture(getBackgroundImage());
+ if (tabWidget)
+ tabWidget->showPage(imagesListView);
+ }
+
+
+ emit setWindowCaption(url.fileName());
+ setModified(false);
+ return true;
+}
+
+/**
+ * Finds the first html element which contains the given text.
+ * Returns the first matching element.
+ * Returns 0L if no element was found.
+ */
+HtmlElement* KImageMapEditor::findHtmlElement(const QString & containingText) {
+ for (HtmlElement * el = _htmlContent.first(); el; el = _htmlContent.next() ) {
+ if (el->htmlCode.contains(containingText,false)) {
+ return el;
+ }
+ }
+ return 0L;
+}
+
+/**
+ * Finds the first html element which contains the given ImageTag.
+ * Returns the first matching element.
+ * Returns 0L if no element was found.
+ */
+HtmlImgElement* KImageMapEditor::findHtmlImgElement(ImageTag* tag) {
+ for (HtmlElement * el = _htmlContent.first(); el; el = _htmlContent.next() ) {
+ HtmlImgElement* imgEl = dynamic_cast<HtmlImgElement*>(el);
+
+ if (imgEl && imgEl->imgTag == tag)
+ return imgEl;
+ }
+ return 0L;
+}
+
+void KImageMapEditor::addMap(const QString & name = QString::null) {
+ HtmlMapElement* el = new HtmlMapElement("\n<map></map>");
+ MapTag* map = new MapTag();
+ map->name = name;
+ el->mapTag = map;
+
+ // Try to find the body tag
+ HtmlElement* bodyTag = findHtmlElement("<body");
+
+ // if we found one add the new map right after the body tag
+ if (bodyTag) {
+ uint index = _htmlContent.find(bodyTag);
+
+ // Add a newline before the map
+ _htmlContent.insert(index+1, new HtmlElement("\n"));
+
+ _htmlContent.insert(index+2, el);
+ } // if there is no body tag we add the map to the end of the file
+ else {
+ // Add a newline before the map
+ _htmlContent.append(new HtmlElement("\n"));
+
+ _htmlContent.append(el);
+ kdDebug() << "KImageMapEditor::addMap : No <body found ! Appending new map to the end." << endl;
+ }
+
+ mapsListView->addMap(name);
+ mapsListView->selectMap(name);
+}
+
+/**
+ * Finds the HtmlMapElement in the HtmlContent, that corresponds
+ * to the given map name.<br>
+ * Returns 0L if there exists no map with the given name
+ */
+HtmlMapElement* KImageMapEditor::findHtmlMapElement(const QString & mapName) {
+ for (HtmlElement * el = _htmlContent.first(); el; el = _htmlContent.next() ) {
+ if (dynamic_cast<HtmlMapElement*>(el)) {
+ HtmlMapElement *tagEl = static_cast<HtmlMapElement*>(el);
+ if (tagEl->mapTag->name == mapName) {
+ return tagEl;
+ }
+ }
+ }
+
+ kdWarning() << "KImageMapEditor::findHtmlMapElement: couldn't find map '" << mapName << "'" << endl;
+ return 0L;
+}
+
+/**
+ * Calls setMap with the HtmlMapElement with the given map name
+ */
+void KImageMapEditor::setMap(const QString & mapName) {
+ HtmlMapElement* el = findHtmlMapElement(mapName);
+ if (!el) {
+ kdWarning() << "KImageMapEditor::setMap : Couldn't set map '" << mapName << "', because it wasn't found !" << endl;
+ return;
+ }
+
+ setMap(el);
+
+}
+
+void KImageMapEditor::setMap(MapTag* map) {
+ for (HtmlElement * el = _htmlContent.first(); el; el = _htmlContent.next() ) {
+ HtmlMapElement *tagEl = dynamic_cast<HtmlMapElement*>(el);
+ if (tagEl) {
+ if (tagEl->mapTag == map) {
+ setMap(tagEl);
+ break;
+ }
+ }
+ }
+
+}
+
+void KImageMapEditor::saveAreasToMapTag(MapTag* map) {
+ map->clear();
+ for (Area* a=areas->first();a!=0L;a=areas->next()) {
+ QDict<QString> *dict = new QDict<QString>(17,false);
+ QString *shapeStr = 0L;
+
+ switch (a->type()) {
+ case Area::Rectangle : shapeStr = new QString("rect");break;
+ case Area::Circle : shapeStr = new QString("circle");break;
+ case Area::Polygon : shapeStr = new QString("poly");break;
+ default : continue;
+ }
+
+ dict->insert("shape",shapeStr);
+
+ for (AttributeIterator it = a->firstAttribute();it!=a->lastAttribute();++it) {
+ dict->insert(it.key(),new QString(it.data()));
+ }
+
+ dict->insert("coords",new QString(a->coordsToString()));
+
+ map->append(dict);
+
+ }
+
+ if (defaultArea && defaultArea->finished()) {
+ QDict<QString> *dict = new QDict<QString>(17,false);
+ dict->insert("shape",new QString("default"));
+
+ for (AttributeIterator it = defaultArea->firstAttribute();it!=defaultArea->lastAttribute();++it) {
+ dict->insert(it.key(),new QString(it.data()));
+ }
+
+ map->append(dict);
+ }
+
+}
+
+void KImageMapEditor::setMap(HtmlMapElement* mapElement) {
+ if (currentMapElement) {
+ currentMapElement->mapTag->modified=true;
+ currentMapElement->htmlCode = getHTMLImageMap();
+ saveAreasToMapTag(currentMapElement->mapTag);
+ }
+
+ currentMapElement = mapElement;
+ MapTag* map = currentMapElement->mapTag;
+
+ // Remove old areas only if a new map is loaded
+ deleteAllAreas();
+ delete defaultArea;
+ defaultArea = 0L;
+// kdDebug() << "KImageMapEditor::setMap : Setting new map : " << map->name << endl;
+ _mapName = map->name;
+ for (AreaTag *tag=map->first();tag!=0L;tag=map->next())
+ {
+ QString shape="rect";
+ if (tag->find("shape"))
+ shape=*tag->find("shape");
+
+ Area::ShapeType type=Area::Rectangle;
+ if (shape=="circle")
+ type=Area::Circle;
+ else if (shape=="poly")
+ type=Area::Polygon;
+ else if (shape=="default")
+ type=Area::Default;
+
+ Area* a=AreaCreator::create(type);
+
+ if (tag->find("href"))
+ a->setAttribute("href",*tag->find("href"));
+
+ if (tag->find("alt"))
+ a->setAttribute("alt",*tag->find("alt"));
+
+ if (tag->find("target"))
+ a->setAttribute("target",*tag->find("target"));
+
+ if (tag->find("title"))
+ a->setAttribute("title",*tag->find("title"));
+
+ if (tag->find("onclick"))
+ a->setAttribute("onclick",*tag->find("onclick"));
+
+ if (tag->find("onmousedown"))
+ a->setAttribute("onmousedown",*tag->find("onmousedown"));
+
+ if (tag->find("onmouseup"))
+ a->setAttribute("onmouseup",*tag->find("onmouseup"));
+
+ if (tag->find("onmouseover"))
+ a->setAttribute("onmouseover",*tag->find("onmouseover"));
+
+ if (tag->find("onmousemove"))
+ a->setAttribute("onmousemove",*tag->find("onmousemove"));
+
+ if (tag->find("onmouseout"))
+ a->setAttribute("onmouseout",*tag->find("onmouseout"));
+
+
+
+ if (type==Area::Default) {
+ defaultArea=a;
+ defaultArea->setFinished(true);
+ continue;
+ }
+
+ if (tag->find("coords"))
+ a->setCoords(*tag->find("coords"));
+
+ a->setMoving(false);
+ addArea(a);
+ }
+
+ updateAllAreas();
+
+ setMapActionsEnabled(true);
+}
+
+/**
+ * Sets wether actions that depend on an selected map
+ * are enabled
+ */
+void KImageMapEditor::setMapActionsEnabled(bool b) {
+ mapDeleteAction->setEnabled(b);
+ mapDefaultAreaAction->setEnabled(b);
+ mapNameAction->setEnabled(b);
+
+ arrowAction->setChecked(true);
+ slotDrawArrow();
+
+ arrowAction->setEnabled(b);
+ circleAction->setEnabled(b);
+ rectangleAction->setEnabled(b);
+ polygonAction->setEnabled(b);
+ freehandAction->setEnabled(b);
+ addPointAction->setEnabled(b);
+ removePointAction->setEnabled(b);
+
+}
+
+QString KImageMapEditor::getHtmlCode() {
+ if (currentMapElement) {
+ currentMapElement->htmlCode = getHTMLImageMap();
+ }
+
+ QString result;
+
+ HtmlElement *el;
+ for ( el = _htmlContent.first(); el; el = _htmlContent.next() ) {
+ result += el->htmlCode;
+ //kdDebug() << "KImageMapEditor::getHtmlCode : Writing : " << el->htmlCode << endl;
+
+ }
+ return result;
+}
+
+void KImageMapEditor::saveImageMap(const KURL & url)
+{
+ QFileInfo fileInfo(url.path());
+
+ if (!QFileInfo(url.directory()).isWritable()) {
+ KMessageBox::error(widget(),
+ i18n("<qt>The file <i>%1</i> could not be saved, because you do not have the required write permissions.</qt>").arg(url.path()));
+ return;
+ }
+
+ if (!backupFileCreated) {
+ QString backupFile = url.path()+"~";
+ KIO::file_copy(url, KURL::fromPathOrURL( backupFile ), -1, true, false, false);
+ backupFileCreated = true;
+ }
+
+ setModified(false);
+
+ if (mapName().isEmpty()) {
+ mapEditName();
+ }
+ QFile file(url.path());
+ file.open(IO_WriteOnly);
+
+ QTextStream t(&file);
+
+ if (_htmlContent.isEmpty()) {
+ t << "<html>\n"
+ << "<head>\n"
+ << " <title></title>\n"
+ << "</head>\n"
+ << "<body>\n"
+ << " " << getHTMLImageMap()
+ << "\n"
+ << " <img src=\"" << QExtFileInfo::toRelative(_imageUrl,KURL( url.directory() )).path() << "\""
+ << " usemap=\"#" << _mapName << "\""
+ << " width=\"" << drawZone->picture().width() << "\""
+ << " height=\"" << drawZone->picture().height() << "\">\n"
+ << "</body>\n"
+ << "</html>";
+ } else
+ {
+ t << getHtmlCode();
+ }
+
+ file.close();
+
+}
+
+
+void KImageMapEditor::slotCut()
+{
+ if ( 0 == currentSelected->count() )
+ return;
+ delete copyArea;
+
+ copyArea= static_cast< AreaSelection* > (currentSelected->clone());
+ pasteAction->setEnabled(true);
+ KCommand *command= new CutCommand(this,*currentSelected);
+ commandHistory()->addCommand( command ,true);
+}
+
+
+void KImageMapEditor::slotDelete()
+{
+ if ( 0 == currentSelected->count() )
+ return;
+
+ KCommand *command= new DeleteCommand(this,*currentSelected);
+ commandHistory()->addCommand( command ,true);
+}
+
+void KImageMapEditor::slotCopy()
+{
+ delete copyArea;
+
+ copyArea = static_cast< AreaSelection* > (currentSelected->clone());
+ pasteAction->setEnabled(true);
+}
+
+void KImageMapEditor::slotPaste()
+{
+ if (!copyArea)
+ return;
+
+ copyArea->moveBy(5,5);
+ if (copyArea->rect().x()>= drawZone->getImageRect().width() ||
+ copyArea->rect().y()>= drawZone->getImageRect().height())
+ copyArea->moveTo(0,0);
+
+ if (copyArea->rect().width()>drawZone->getImageRect().width() ||
+ copyArea->rect().height()>drawZone->getImageRect().height())
+ return;
+
+ AreaSelection *a=static_cast< AreaSelection* > (copyArea->clone());
+ commandHistory()->addCommand( new PasteCommand(this,*a),true);
+ delete a;
+// addAreaAndEdit(a);
+}
+
+
+
+void KImageMapEditor::slotBackOne()
+{
+ if (currentSelected->isEmpty())
+ return;
+
+ AreaList list = currentSelected->getAreaList();
+
+
+ Area *a = 0L;
+ // move every selected Area one step lower
+ for (int i=areas->count()-2; i > -1; i--)
+ {
+ if (list.find( areas->at(i) ) > -1 )
+ {
+ a = areas->at(i);
+ areas->remove(a);
+ areas->insert((uint)i+1,a);
+ a->listViewItem()->moveItem( areas->at(i)->listViewItem() );
+ }
+ }
+ // to update the up and down buttons
+ updateUpDownBtn();
+
+}
+
+void KImageMapEditor::slotForwardOne()
+{
+ if (currentSelected->isEmpty())
+ return;
+
+ AreaList list = currentSelected->getAreaList();
+
+ Area *a = 0L;
+ // move every selected Area one step higher
+ for (int i=1; i < (int)areas->count(); i++)
+ {
+ if (list.find( areas->at(i) ) > -1 )
+ {
+ a = areas->at(i);
+ areas->remove(a);
+ areas->insert((uint)i-1,a);
+ areas->at(i)->listViewItem()->moveItem( a->listViewItem() );
+ }
+ }
+ // to update the up and down buttons
+ updateUpDownBtn();
+}
+
+void KImageMapEditor::slotToBack()
+{
+ if (currentSelected->isEmpty())
+ return;
+
+ while (backOneAction->isEnabled())
+ slotBackOne();
+}
+
+void KImageMapEditor::slotToFront()
+{
+ if (currentSelected->isEmpty())
+ return;
+
+ while (forwardOneAction->isEnabled())
+ slotForwardOne();
+}
+
+
+void KImageMapEditor::slotMoveUp()
+{
+ QRect r=selected()->rect();
+ selected()->setMoving(true);
+ selected()->moveBy(0,-1);
+
+ commandHistory()->addCommand(
+ new MoveCommand( this, selected(), r.topLeft() ) ,true );
+ selected()->setMoving(false);
+ slotAreaChanged(selected());
+ slotUpdateSelectionCoords();
+}
+
+void KImageMapEditor::slotMoveDown()
+{
+ QRect r=selected()->rect();
+ selected()->setMoving(true);
+ selected()->moveBy(0,1);
+
+ commandHistory()->addCommand(
+ new MoveCommand( this, selected(), r.topLeft() ) ,true );
+ selected()->setMoving(false);
+ slotAreaChanged(selected());
+ slotUpdateSelectionCoords();
+}
+
+void KImageMapEditor::slotMoveLeft()
+{
+ QRect r=selected()->rect();
+ selected()->setMoving(true);
+ selected()->moveBy(-1,0);
+
+ commandHistory()->addCommand(
+ new MoveCommand( this, selected(), r.topLeft() ) ,true );
+ selected()->setMoving(false);
+ slotAreaChanged(selected());
+ slotUpdateSelectionCoords();
+}
+
+void KImageMapEditor::slotMoveRight()
+{
+ QRect r=selected()->rect();
+ selected()->setMoving(true);
+ selected()->moveBy(1,0);
+
+ commandHistory()->addCommand(
+ new MoveCommand( this, selected(), r.topLeft() ) ,true );
+ selected()->setMoving(false);
+ slotAreaChanged(selected());
+ slotUpdateSelectionCoords();
+}
+
+void KImageMapEditor::slotCancelDrawing()
+{
+ drawZone->cancelDrawing();
+}
+
+void KImageMapEditor::slotIncreaseHeight()
+{
+ Area *oldArea=selected()->clone();
+
+ QRect r = selected()->rect();
+ r.setHeight( r.height()+1 );
+ r.moveBy(0,-1);
+
+ selected()->setRect(r);
+
+ commandHistory()->addCommand(
+ new ResizeCommand( this, selected(), oldArea ) ,true );
+ slotAreaChanged(selected());
+ slotUpdateSelectionCoords();
+}
+
+void KImageMapEditor::slotDecreaseHeight()
+{
+ Area *oldArea=selected()->clone();
+
+ QRect r = selected()->rect();
+ r.setHeight( r.height()-1 );
+ r.moveBy(0,1);
+
+ selected()->setRect(r);
+
+ commandHistory()->addCommand(
+ new ResizeCommand( this, selected(), oldArea ) ,true );
+ slotAreaChanged(selected());
+ slotUpdateSelectionCoords();
+}
+
+void KImageMapEditor::slotIncreaseWidth()
+{
+ Area *oldArea=selected()->clone();
+
+ QRect r = selected()->rect();
+ r.setWidth( r.width()+1 );
+
+ selected()->setRect(r);
+
+ commandHistory()->addCommand(
+ new ResizeCommand( this, selected(), oldArea ) ,true );
+ slotAreaChanged(selected());
+ slotUpdateSelectionCoords();
+}
+
+void KImageMapEditor::slotDecreaseWidth()
+{
+ Area *oldArea=selected()->clone();
+
+ QRect r = selected()->rect();
+ r.setWidth( r.width()-1 );
+
+ selected()->setRect(r);
+
+ commandHistory()->addCommand(
+ new ResizeCommand( this, selected(), oldArea ) ,true );
+ slotAreaChanged(selected());
+ slotUpdateSelectionCoords();
+}
+
+void KImageMapEditor::slotHightlightAreas()
+{
+ bool b = highlightAreasAction->isChecked();
+
+// highlightAreasAction->setChecked(b);
+ Area::highlightArea = b;
+ updateAllAreas();
+ drawZone->viewport()->repaint();
+}
+
+void KImageMapEditor::slotShowAltTag()
+{
+ bool b = showAltAction->isChecked();
+// showAltAction->setChecked(b);
+ Area::showAlt = b;
+ drawZone->viewport()->repaint();
+}
+
+void KImageMapEditor::mapNew()
+{
+ QString mapName = mapsListView->getUnusedMapName();
+ addMap(mapName);
+ mapEditName();
+}
+
+void KImageMapEditor::mapDelete()
+{
+ if (mapsListView->count() == 0)
+ return;
+
+ QString selectedMap = mapsListView->selectedMap();
+
+ int result = KMessageBox::warningContinueCancel(widget(),
+ i18n("<qt>Are you sure you want to delete the map <i>%1</i>?"
+ " <br><b>There is no way to undo this.</b></qt>").arg(selectedMap),
+ i18n("Delete Map?"),KGuiItem(i18n("&Delete"),"editdelete"));
+
+ if (result == KMessageBox::No)
+ return;
+
+
+
+ mapsListView->removeMap(selectedMap);
+ HtmlMapElement* mapEl = findHtmlMapElement(selectedMap);
+ _htmlContent.remove(mapEl);
+ if (mapsListView->count() == 0) {
+
+ currentMapElement = 0L;
+ deleteAllAreas();
+ setMapActionsEnabled(false);
+ }
+ else {
+ // The old one was deleted, so the new one got selected
+ setMap(mapsListView->selectedMap());
+ }
+}
+
+void KImageMapEditor::mapPreview() {
+ HTMLPreviewDialog dialog(widget(), url(), getHtmlCode());
+ dialog.exec();
+}
+
+void KImageMapEditor::deleteAllMaps()
+{
+ deleteAllAreas();
+ mapsListView->clear();
+ if (isReadWrite()) {
+ mapDeleteAction->setEnabled(false);
+ mapDefaultAreaAction->setEnabled(false);
+ mapNameAction->setEnabled(false);
+ }
+}
+
+/**
+ * Doesn't call the closeURL method, because
+ * we need the URL for the session management
+ */
+bool KImageMapEditor::queryClose() {
+ if ( ! isModified() )
+ return true;
+
+ switch ( KMessageBox::warningYesNoCancel( widget(),
+ i18n("<qt>The file <i>%1</i> has been modified.<br>Do you want to save it?</qt>").arg(url().fileName()), QString::null, KStdGuiItem::save(), KStdGuiItem::discard()) ) {
+ case KMessageBox::Yes :
+ saveFile();
+ return true;
+ case KMessageBox::No :
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool KImageMapEditor::closeURL()
+{
+ bool result = KParts::ReadWritePart::closeURL();
+ if (!result)
+ return false;
+
+ _htmlContent.clear();
+ deleteAllMaps();
+ imagesListView->clear();
+
+ delete copyArea;
+ copyArea=0L;
+
+ delete defaultArea;
+ defaultArea=0L;
+
+ currentMapElement = 0L;
+
+ init();
+ emit setWindowCaption("");
+
+ return true;
+
+}
+
+void KImageMapEditor::addImage(const KURL & imgUrl) {
+ if (imgUrl.isEmpty())
+ return;
+
+ QString relativePath ( QExtFileInfo::toRelative(imgUrl, KURL( url().directory() )).path() );
+
+ QString imgHtml = QString("<img src=\"")+relativePath+QString("\">");
+ ImageTag *imgTag = new ImageTag();
+ imgTag->insert("tagname",new QString("img"));
+ imgTag->insert("src", new QString(relativePath));
+
+ HtmlImgElement *imgEl = new HtmlImgElement(imgHtml);
+ imgEl->imgTag = imgTag;
+
+ HtmlElement *bodyEl = findHtmlElement("<body");
+ if (bodyEl) {
+ int bodyIndex = _htmlContent.find(bodyEl);
+ _htmlContent.insert(bodyIndex+1, new HtmlElement("\n"));
+ _htmlContent.insert(bodyIndex+2, imgEl);
+ }
+ else {
+ _htmlContent.append(new HtmlElement("\n"));
+ _htmlContent.append(imgEl);
+ }
+
+ imagesListView->addImage(imgTag);
+ imagesListView->selectImage(imgTag);
+ setImageActionsEnabled(true);
+
+ setModified(true);
+}
+
+/**
+ * Sets whether the image actions that depend on an
+ * selected image are enabled
+ */
+void KImageMapEditor::setImageActionsEnabled(bool b) {
+ imageRemoveAction->setEnabled(b);
+ imageUsemapAction->setEnabled(b);
+}
+
+
+void KImageMapEditor::imageAdd() {
+ KURL imgUrl = KFileDialog::getImageOpenURL();
+ addImage(imgUrl);
+}
+
+void KImageMapEditor::imageRemove() {
+ ImageTag* imgTag = imagesListView->selectedImage();
+ HtmlImgElement* imgEl = findHtmlImgElement(imgTag);
+ imagesListView->removeImage(imgTag);
+ _htmlContent.remove(imgEl);
+
+ if (imagesListView->childCount() == 0) {
+ setPicture(getBackgroundImage());
+ setImageActionsEnabled(false);
+ }
+ else {
+ ImageTag* selected = imagesListView->selectedImage();
+ if (selected) {
+ QString *url = selected->find("src");
+ if (url) {
+ setPicture(KURL(*url));
+ }
+ }
+ }
+
+ setModified(true);
+}
+
+void KImageMapEditor::imageUsemap() {
+
+ bool ok=false;
+ ImageTag* imageTag = imagesListView->selectedImage();
+ if ( ! imageTag)
+ return;
+
+ QString usemap;
+
+ if (imageTag->find("usemap"))
+ usemap=*imageTag->find("usemap");
+
+ QStringList maps = mapsListView->getMaps();
+ int index = maps.findIndex(usemap);
+ if (index == -1) {
+ maps.prepend("");
+ index = 0;
+ }
+
+#if KDE_IS_VERSION(3, 1, 90)
+ QString input = KInputDialog::getItem(i18n("Enter Usemap"),
+#else
+ QString input = QInputDialog::getItem(i18n("Enter Usemap"),
+#endif
+ i18n("Enter the usemap value:"),
+ maps,index,true,&ok,widget());
+ if (ok) {
+ imageTag->replace("usemap", new QString(input));
+ imagesListView->updateImage(imageTag);
+ setModified(true);
+
+ // Update the htmlCode of the HtmlElement
+ HtmlImgElement* imgEl = findHtmlImgElement(imageTag);
+
+ imgEl->htmlCode = "<";
+ QString *tagName = imgEl->imgTag->find("tagname");
+ imgEl->htmlCode += QString(*tagName);
+
+ QDictIterator<QString> it( *imgEl->imgTag );
+ for( ; it.current(); ++it ) {
+ if (it.currentKey() != "tagname") {
+ imgEl->htmlCode += " " + it.currentKey() + "=\"";
+ imgEl->htmlCode += *it.current();
+ imgEl->htmlCode += "\"";
+ }
+ }
+
+ imgEl->htmlCode += ">";
+
+ }
+}
+
+void KImageMapEditor::configureShowAreaList() {
+ if (configureShowAreaListAction->isChecked())
+ mainDock->makeDockVisible(areaDock);
+ else
+ mainDock->makeDockInvisible(areaDock);
+}
+
+void KImageMapEditor::configureShowMapList() {
+ if (configureShowMapListAction->isChecked())
+ mainDock->makeDockVisible(mapsDock);
+ else
+ mainDock->makeDockInvisible(mapsDock);
+}
+
+void KImageMapEditor::configureShowImageList() {
+ if (configureShowImageListAction->isChecked())
+ mainDock->makeDockVisible(imagesDock);
+ else
+ mainDock->makeDockInvisible(imagesDock);
+}
+
+void KImageMapEditor::dockingStateChanged() {
+ if (areaDock) {
+ configureShowImageListAction->setChecked( imagesDock->isVisible() );
+ configureShowAreaListAction->setChecked( areaDock->isVisible() );
+ configureShowMapListAction->setChecked( mapsDock->isVisible() );
+ }
+}
diff --git a/kimagemapeditor/kimagemapeditor.desktop b/kimagemapeditor/kimagemapeditor.desktop
new file mode 100644
index 00000000..263c7536
--- /dev/null
+++ b/kimagemapeditor/kimagemapeditor.desktop
@@ -0,0 +1,55 @@
+[Desktop Entry]
+Type=Application
+MimeType=text/html;
+Exec=kimagemapeditor -caption "%c" %i %m
+Icon=kimagemapeditor
+Terminal=false
+Name=KImageMapEditor
+Name[ne]=केडीई छवि मानचितà¥à¤° समà¥à¤ªà¤¾à¤¦à¤•
+Name[pt_BR]=KEditor de Mapeamento de Imagem
+Name[sk]=KImage editor mapy
+Name[sv]=Kimagemapeditor
+Name[ta]=Kவடிவம௠வரைபà¯à®ªà®Ÿà®®à¯ திரà¯à®¤à¯à®¤à®¿
+Name[tg]=KМуҳаррири таÑвири ҳарита
+Name[tr]=K Resim Haritası Düzenleyicisi
+GenericName=HTML Image Map Editor
+GenericName[bg]=Редактор на Ð¼Ð°Ñ€ÐºÐ¸Ñ€Ð°Ð½Ð¸Ñ Ð½Ð° Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð·Ð° HTML
+GenericName[ca]=Un editor de mapes d'imatge HTML
+GenericName[cs]=Editor HTML map
+GenericName[da]=HTML editor af kortbilleder
+GenericName[de]=Editor für HTML-Bildkarten (Imagemaps)
+GenericName[el]=HTML επεξεÏγαστής εικόνων
+GenericName[es]=Editor de mapas de imágenes HTML
+GenericName[et]=Hüperpildiredaktor
+GenericName[eu]=HTML irudi-mapa editorea
+GenericName[fa]=ویرایشگر نگاشت تصویر زنگام
+GenericName[fi]=HTML-kuvaeditori
+GenericName[fr]=Éditeur d'hyperimages HTML
+GenericName[gl]=Editor de mapas de imaxes HTML
+GenericName[hu]=HTML-térképszerkesztő
+GenericName[is]=HTML myndakortsritill
+GenericName[it]=Editor per le mappe di immagini HTML
+GenericName[ja]=HTML イメージマップエディタ
+GenericName[ka]=HTML გáƒáƒ›áƒáƒ¡áƒáƒ®áƒ£áƒšáƒ”ბის რუქის რედáƒáƒ¥áƒ¢áƒáƒ áƒ˜
+GenericName[lt]=HTML paveikslėlių žemėlapių rengyklė
+GenericName[ms]=Penyunting Peta Imej HTML
+GenericName[nds]=Editor för HTML-Bildkoorten
+GenericName[ne]=à¤à¤šà¤Ÿà¥€à¤à¤®à¤à¤² छवि मानचितà¥à¤° समà¥à¤ªà¤¾à¤¦à¤•
+GenericName[nl]=HTML imagemap editor
+GenericName[pa]=HTML ਚਿੱਤਰ ਨਕਸ਼ਾ ਸੰਪਾਦਕ
+GenericName[pl]=Edytor map obrazków HTML
+GenericName[pt]=Editor de Mapas de Imagem HTML
+GenericName[pt_BR]=Editor de Mapeamento de Imagem HTML
+GenericName[sk]=Editor HTML mapy obrázkov
+GenericName[sl]=Urejevalnik slikovnih zemljevidov v HTML
+GenericName[sr]=Уређивач HTML Ñликовне мапе
+GenericName[sr@Latn]=UreÄ‘ivaÄ HTML slikovne mape
+GenericName[sv]=Redigering av HTML-bildkartor
+GenericName[ta]=HTML வடிவம௠வரைபà¯à®ªà®Ÿà®®à¯ திரà¯à®¤à¯à®¤à®¿
+GenericName[tg]=Муҳаррири таÑвири ҳаритаи HTML
+GenericName[tr]=HTML Resim Haritası Düzenleyicisi
+GenericName[uk]=Редактор карт зображень HTML
+GenericName[zh_CN]=HTML 图åƒæ˜ å°„编辑器
+GenericName[zh_HK]=HTML å½±åƒåœ°åœ–編輯器
+GenericName[zh_TW]=HTML å½±åƒåœ°åœ–編輯器
+Categories=Qt;KDE;Development;WebDevelopment;
diff --git a/kimagemapeditor/kimagemapeditor.h b/kimagemapeditor/kimagemapeditor.h
new file mode 100644
index 00000000..bf76349e
--- /dev/null
+++ b/kimagemapeditor/kimagemapeditor.h
@@ -0,0 +1,460 @@
+/***************************************************************************
+ imagemapeditor.h - description
+ -------------------
+ begin : Wed Apr 4 2001
+ copyright : (C) 2001 by Jan SchÃ?fer
+ email : janschaefer@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef KIMAGEMAPDIALOG_H
+#define KIMAGEMAPDIALOG_H
+
+#include <qptrlist.h>
+#include <qobjectlist.h>
+#include <qdict.h>
+#include <qimage.h>
+#include <kurl.h>
+#include <kparts/part.h>
+#include <kparts/browserextension.h>
+#include <kparts/factory.h>
+
+#include <kdeversion.h>
+
+#include "kimearea.h"
+
+/**
+ *@author Jan Schaefer
+ */
+
+
+class QListView;
+class QPushButton;
+class DrawZone;
+class QComboBox;
+class QListViewItem;
+class KToggleAction;
+
+
+
+
+/**
+ * Stores an area tag and all its attributes
+ */
+typedef QDict<QString> AreaTag;
+
+/**
+ * Stores an image tag and all its attributes
+ * the origcode attribute hold the original htmlcode
+ * of this tag
+ */
+typedef QDict<QString> ImageTag;
+
+/**
+ * Only a small class to give a list of AreaTags a name
+ */
+class MapTag : public QPtrList<AreaTag> {
+public:
+ MapTag();
+ QString name;
+ bool modified;
+};
+
+
+class HtmlElement {
+public:
+ HtmlElement(const QString & s) {
+ htmlCode = s;
+ };
+ virtual ~HtmlElement() {}
+ ;
+ QString htmlCode;
+};
+
+class HtmlMapElement : public HtmlElement {
+public:
+ HtmlMapElement(const QString & s) : HtmlElement(s) {
+ mapTag = 0L;
+ };
+
+ virtual ~HtmlMapElement() {};
+
+ MapTag *mapTag;
+};
+
+class HtmlImgElement : public HtmlElement {
+public:
+HtmlImgElement(const QString & s) : HtmlElement(s) {
+ imgTag = 0L;
+ };
+ virtual ~HtmlImgElement() {}
+ ;
+ ImageTag *imgTag;
+};
+
+/**
+ * Stores the hole HTML content in a List.
+ */
+class HtmlContent : public QPtrList<HtmlElement> {}
+;
+
+
+class KSelectAction;
+class KRadioAction;
+class KRecentFilesAction;
+class KAction;
+#if KDE_VERSION < 300
+ class KAccel;
+#endif
+///class QListViewItem;
+class KCommandHistory;
+class KApplication;
+class QTabWidget;
+class AreaListView;
+class ImagesListView;
+class MapsListView;
+class KDockWidget;
+class KDockMainWindow;
+
+// needed by the statusbar
+#define STATUS_CURSOR 1000
+#define STATUS_SELECTION 1001
+
+class KImageMapEditor : public KParts::ReadWritePart {
+ Q_OBJECT
+public :
+ enum ToolType { Selection, Rectangle, Circle, Polygon, Freehand, AddPoint, RemovePoint };
+
+ KImageMapEditor(QWidget *parentWidget, const char *,
+ QObject *parent, const char *name, const QStringList & args = QStringList());
+ virtual ~KImageMapEditor();
+
+ static KAboutData *createAboutData();
+ static KConfig *config();
+
+ /**
+ * Makes sure, that the actions cut, copy, delete and
+ * show properties
+ * can only be executed if sth. is selected.
+ **/
+ void updateActionAccess();
+
+ DrawZone* getDrawZone() {
+ return drawZone;
+ };
+
+ void addAreaAndEdit(Area*);
+ void addArea(Area*);
+ AreaListIterator areaList() const;
+ KImageMapEditor::ToolType currentToolType() const;
+ void deleteSelected();
+ void deleteArea( Area * area);
+ void deleteAllAreas();
+ void deselectAll();
+ void deselect(Area* s);
+ void deselectWithoutUpdate(Area*);
+ QString getHTMLImageMap() const;
+ Area* onArea(const QPoint & p) const;
+ QPixmap makeListViewPix(Area &) ;
+ QString mapName() const;
+ void select(Area*);
+ void selectWithoutUpdate(Area*);
+ void select(QListViewItem*);
+ AreaSelection* selected() const;
+ void setPicture(const QImage & pix);
+ int showTagEditor(Area *);
+ KCommandHistory *commandHistory() const;
+
+ KApplication* app() const;
+
+ // Only refreshes the listView
+ void updateSelection() const;
+
+ void readConfig();
+ void writeConfig();
+
+ virtual void readProperties(KConfig *);
+ virtual void saveProperties(KConfig *);
+ virtual bool closeURL();
+ bool queryClose();
+ virtual void setReadWrite(bool);
+ QString getHtmlCode();
+
+ /**
+ * Reimplemented to disable and enable Save action
+ */
+ virtual void setModified(bool);
+
+ /**
+ * Opens the given file.
+ * If it's an HTML file openURL is called
+ * If it's an Image, the image is added to the image list
+ */
+ void openFile(const KURL &);
+
+ /**
+ * Opens the last URL the user worked with.
+ * Sets also, the last map and the last image
+ */
+ void openLastURL(KConfig*);
+
+ void readConfig(KConfig*);
+ void writeConfig(KConfig*);
+
+ virtual bool openURL(const KURL & url);
+
+protected:
+ void init();
+ bool openHTMLFile(const KURL &, const QString & mapName = QString::null, const QString & imagePath = QString::null);
+ void saveImageMap(const KURL &);
+
+ /**
+ * Returns a language dependend background picture, with
+ * the text : Drop an image or html file
+ */
+ QImage getBackgroundImage();
+
+
+ /**
+ * Saves information to restore the last working state
+ */
+ void saveLastURL(KConfig*);
+
+
+private:
+ // Stores the hole html file in a List
+ // The entries are either a MapTag an ImageTag or a QString
+ HtmlContent _htmlContent;
+
+ // the url of the working image;
+ KURL _imageUrl;
+ QString _mapName;
+ QImage _backgroundImage;
+
+ bool backupFileCreated;
+
+ KImageMapEditor::ToolType _currentToolType;
+ AreaList *areas;
+ AreaSelection *currentSelected;
+ AreaSelection *copyArea;
+ Area *defaultArea;
+ DrawZone* drawZone;
+ QTabWidget* tabWidget;
+ AreaListView *areaListView;
+ ImagesListView* imagesListView;
+ MapsListView* mapsListView;
+ HtmlMapElement* currentMapElement;
+
+ //
+ // Actions
+ //
+ KSelectAction* zoomAction;
+ KRadioAction *arrowAction;
+ KRadioAction *circleAction;
+ KRadioAction *rectangleAction;
+ KRadioAction *polygonAction;
+ KRadioAction *freehandAction;
+ KRadioAction *addPointAction;
+ KRadioAction *removePointAction;
+
+ KAction *cutAction;
+ KAction *deleteAction;
+ KAction *copyAction;
+ KAction *pasteAction;
+ KAction *zoomInAction;
+ KAction *zoomOutAction;
+
+ KAction *mapNewAction;
+ KAction *mapDeleteAction;
+ KAction *mapNameAction;
+ KAction *mapDefaultAreaAction;
+
+ KAction *imageAddAction;
+ KAction *imageRemoveAction;
+ KAction *imageUsemapAction;
+
+ KToggleAction *highlightAreasAction;
+ KToggleAction *showAltAction;
+
+ KAction *areaPropertiesAction;
+
+ KAction *moveLeftAction;
+ KAction *moveRightAction;
+ KAction *moveUpAction;
+ KAction *moveDownAction;
+
+ KAction *increaseWidthAction;
+ KAction *decreaseWidthAction;
+ KAction *increaseHeightAction;
+ KAction *decreaseHeightAction;
+
+ KAction *toFrontAction;
+ KAction *toBackAction;
+ KAction *forwardOneAction;
+ KAction *backOneAction;
+
+ KToggleAction* configureShowAreaListAction;
+ KToggleAction* configureShowMapListAction;
+ KToggleAction* configureShowImageListAction;
+
+
+ KRecentFilesAction* recentFilesAction;
+
+ #if KDE_VERSION < 300
+ KAccel *accel;
+ #endif
+
+ KDockMainWindow *mainDock;
+ KDockWidget* areaDock;
+ KDockWidget* mapsDock;
+ KDockWidget* imagesDock;
+
+ KCommandHistory *_commandHistory;
+ int maxAreaPreviewHeight;
+
+ QString cursorStatusText;
+ QString selectionStatusText;
+
+ void setupActions();
+ void setupStatusBar();
+ void updateStatusBar();
+ /* refreshes all Areas, only used by preferences dialog
+ * updates only the preview pictures*/
+ void updateAllAreas();
+ void updateUpDownBtn();
+
+ QDict<QString> getTagAttributes(QTextStream & s,QString &);
+
+ void setMap(HtmlMapElement*);
+ void setMap(MapTag*);
+ void addMap(const QString &);
+
+ // Returns the entire html file as a String
+ HtmlElement* findHtmlElement(const QString &);
+ HtmlImgElement* findHtmlImgElement(ImageTag*);
+ HtmlMapElement* findHtmlMapElement(const QString &);
+ void deleteAllMaps();
+ void addImage(const KURL &);
+ void setImageActionsEnabled(bool);
+ void setMapActionsEnabled(bool);
+
+ void saveAreasToMapTag(MapTag*);
+ void showPopupMenu(const QPoint &, const QString &);
+ void drawToCenter(QPainter* p, const QString & str, int y, int width);
+
+public slots:
+ void slotChangeStatusCoords(int x,int y);
+ void slotUpdateSelectionCoords();
+ void slotUpdateSelectionCoords( const QRect &);
+ void slotAreaChanged(Area *);
+ void slotShowMainPopupMenu(const QPoint &);
+ void slotShowMapPopupMenu(QListViewItem *, const QPoint &);
+ void slotShowImagePopupMenu(QListViewItem *, const QPoint &);
+ void slotConfigChanged();
+ void setPicture(const KURL & url);
+ void setMap(const QString &);
+ void setMapName(const QString & s);
+
+
+protected slots:
+ // overriden from KReadWritePart
+ virtual bool openFile();
+
+ virtual bool saveFile() {
+ saveImageMap( url() );
+// setModified(false);
+ return true;
+ }
+
+ void fileOpen();
+ void fileSaveAs();
+ void fileSave();
+ void fileClose();
+
+ void slotShowPopupMenu(QListViewItem*,const QPoint &);
+ void slotShowPreferences();
+ void slotHightlightAreas();
+ void slotShowAltTag();
+ void slotSelectionChanged();
+
+ int showTagEditor(QListViewItem *item);
+ int showTagEditor();
+
+ void slotZoom();
+ void slotZoomIn();
+ void slotZoomOut();
+
+ void slotCut();
+ void slotCopy();
+ void slotPaste();
+ void slotDelete();
+
+ void slotDrawArrow();
+ void slotDrawCircle();
+ void slotDrawRectangle();
+ void slotDrawPolygon();
+ void slotDrawFreehand();
+ void slotDrawAddPoint();
+ void slotDrawRemovePoint();
+
+ void mapDefaultArea();
+ void mapNew();
+ void mapDelete();
+ void mapEditName();
+ void mapShowHTML();
+ void mapPreview();
+
+ void slotBackOne();
+ void slotForwardOne();
+ void slotToBack();
+ void slotToFront();
+
+ void slotMoveUp();
+ void slotMoveDown();
+ void slotMoveLeft();
+ void slotMoveRight();
+
+ void slotIncreaseHeight();
+ void slotDecreaseHeight();
+ void slotIncreaseWidth();
+ void slotDecreaseWidth();
+
+ void slotCancelDrawing();
+
+ void configureShowAreaList();
+ void configureShowMapList();
+ void configureShowImageList();
+
+
+ // void slotPreferences();
+ void imageAdd();
+ void imageRemove();
+ void imageUsemap();
+
+ void dockingStateChanged();
+
+};
+
+
+inline KImageMapEditor::ToolType KImageMapEditor::currentToolType() const {
+ return _currentToolType;
+}
+
+inline QString KImageMapEditor::mapName() const {
+ return _mapName;
+}
+
+inline KCommandHistory* KImageMapEditor::commandHistory() const {
+ return _commandHistory;
+}
+
+
+#endif
diff --git a/kimagemapeditor/kimagemapeditorpart.desktop b/kimagemapeditor/kimagemapeditorpart.desktop
new file mode 100644
index 00000000..758b510a
--- /dev/null
+++ b/kimagemapeditor/kimagemapeditorpart.desktop
@@ -0,0 +1,54 @@
+[Desktop Entry]
+Type=Service
+MimeType=text/html
+Icon=kimagemapeditor
+ServiceTypes=KParts/ReadWritePart
+X-KDE-Library=libkimagemapeditor
+Comment=An HTML imagemap editor
+Comment[bg]=Редактор на Ð¼Ð°Ñ€ÐºÐ¸Ñ€Ð°Ð½Ð¸Ñ Ð½Ð° Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð·Ð° HTML
+Comment[ca]=Un editor de mapes d'imatge HTML
+Comment[cs]=Editor HTML map
+Comment[da]=En HTML-editor af kortbilleder
+Comment[de]=Ein Editor für HTML-Bildkarten (Imagemaps)
+Comment[el]=HTML επεξεÏγαστής εικόνων
+Comment[es]=Un editor de mapas de imágenes HTML
+Comment[et]=Hüperpildiredaktor
+Comment[eu]=HTML irudi-mapa editore bat
+Comment[fa]=یک ویرایشگر نگاشت تصویر زنگام
+Comment[fi]=HTML-imagemap -editori
+Comment[fr]=Éditeur d'hyperimages HTML
+Comment[gl]=Un editor de mapas de imaxes HTML
+Comment[hu]=HTML-térképszerkesztő
+Comment[is]=HTML myndakortsritill
+Comment[it]=Un editor per le mappe di immagini HTML
+Comment[ja]=HTML イメージマップエディタ
+Comment[ka]=HTML გáƒáƒ›áƒáƒ¡áƒáƒ®áƒ£áƒšáƒ”ბის რუქის რედáƒáƒ¥áƒ¢áƒáƒ áƒ˜
+Comment[lt]=HTML paveikslėlių žemėlapių rengyklė
+Comment[ms]=Penyunting Peta Imej HTML
+Comment[nds]=En Editor för HTML-Bildkoorten
+Comment[ne]=à¤à¤‰à¤Ÿà¤¾ à¤à¤šà¤Ÿà¥€à¤à¤®à¤à¤² छवि मानचितà¥à¤° समà¥à¤ªà¤¾à¤¦à¤•à¤¸
+Comment[nl]=Een hulpmiddel om HTML imagemaps te maken
+Comment[pl]=Edytor map obrazków HTML
+Comment[pt]=Editor de Mapas de Imagem HTML
+Comment[pt_BR]=Um editor de mapeamento de imagem HTML
+Comment[ru]=Редактор HTML imagemap
+Comment[sk]=Editor HTML mapy obrázkov
+Comment[sl]=Urejevalnik slikovnih zemljevidov v HTML
+Comment[sr]=Уређивач HTML Ñликовне мапе
+Comment[sr@Latn]=UreÄ‘ivaÄ HTML slikovne mape
+Comment[sv]=En editor för HTML-bildkartor
+Comment[ta]=An HTML வடிவம௠வரைபà¯à®ªà®Ÿà®®à¯ திரà¯à®¤à¯à®¤à®¿
+Comment[tg]=Муҳаррири таÑвири ҳаритаи HTML
+Comment[tr]=Bir HTML resim_haritası düzenleyicisi
+Comment[uk]=Редактор imagemap HTML
+Comment[zh_CN]=HTML 图åƒæ˜ å°„编辑器
+Comment[zh_HK]=一個 HTML å½±åƒåœ°åœ–的編輯器
+Comment[zh_TW]=一個 HTML å½±åƒåœ°åœ–的編輯器
+Name=KImageMapEditor
+Name[ne]=केडीई छवि मानचितà¥à¤° समà¥à¤ªà¤¾à¤¦à¤•
+Name[pt_BR]=KEditor de Mapeamento de Imagem
+Name[sk]=KImage editor mapy
+Name[sv]=Kimagemapeditor
+Name[ta]=Kவடிவம௠வரைபà¯à®ªà®Ÿà®®à¯ திரà¯à®¤à¯à®¤à®¿
+Name[tg]=KМуҳаррири таÑвири ҳарита
+Name[tr]=K Resim Haritası Düzenleyicisi
diff --git a/kimagemapeditor/kimagemapeditorpartui.rc b/kimagemapeditor/kimagemapeditorpartui.rc
new file mode 100644
index 00000000..6f6df968
--- /dev/null
+++ b/kimagemapeditor/kimagemapeditorpartui.rc
@@ -0,0 +1,150 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui name="kimagemapeditorpart" version="20">
+ <MenuBar>
+ <Menu name="file">
+ <Action name="file_open"/>
+ <Action name="file_open_recent"/>
+ <Separator/>
+ <Action name="file_save"/>
+ <Action name="file_save_as"/>
+ <Separator/>
+ <Action name="file_close"/>
+ </Menu>
+ <Menu name="edit" noMerge="1">
+ <text>&amp;Edit</text>
+ <Action name="edit_undo" />
+ <Action name="edit_redo" />
+ <Separator/>
+ <Action name="edit_cut" />
+ <Action name="edit_copy" />
+ <Action name="edit_paste" />
+ <Action name="edit_delete" />
+ <Separator/>
+ <Action name="tofront" />
+ <Action name="toback" />
+ <Action name="forwardone" />
+ <Action name="backone" />
+ <Separator/>
+ <Action name="edit_properties" />
+ </Menu>
+ <Menu name="view" >
+ <text>&amp;View</text>
+ <Action name="view_zoom_in"/>
+ <Action name="view_zoom_out"/>
+ <Action name="view_zoom"/>
+ <Separator/>
+ <Action name="view_highlightareas"/>
+ <Action name="view_showalt"/>
+ </Menu>
+ <Menu name="tools" >
+ <text>&amp;Tools</text>
+ <Action name="tool_arrow" />
+ <Action name="tool_circle" />
+ <Action name="tool_rectangle" />
+ <Action name="tool_polygon" />
+ <Action name="tool_freehand" />
+ <Action name="tool_addpoint" />
+ <Action name="tool_removepoint" />
+ </Menu>
+ <Menu name="map" >
+ <text>&amp;Map</text>
+ <Action name="map_name" />
+ <Action name="map_new" />
+ <Action name="map_delete" />
+ <Separator/>
+ <Action name="map_defaultarea" />
+ <Separator/>
+ <Action name="map_showhtml" />
+ <Action name="map_preview" />
+ </Menu>
+ <Menu name="images" >
+ <text>&amp;Image</text>
+ <Action name="image_usemap" />
+ <Action name="image_remove" />
+ <Action name="image_add" />
+ </Menu>
+ <Menu name="settings"><text>&amp;Settings</text>
+ <Separator/>
+ <Action name="configure_show_arealist" group="settings_show"/>
+ <Action name="configure_show_maplist" group="settings_show"/>
+ <Action name="configure_show_imagelist" group="settings_show"/>
+ <Separator/>
+ <Action name="configure_kimagemapeditor" group="settings_configure"/>
+ </Menu>
+ </MenuBar>
+ <StatusBar/>
+ <ToolBar name="mainToolBar">
+ <text>KImageMapEditor Main Toolbar</text>
+ <Action name="file_open"/>
+ <Action name="file_save"/>
+ <Action name="file_save_as"/>
+ <Separator/>
+ <Action name="edit_undo" />
+ <Action name="edit_redo" />
+ <Separator/>
+ <Action name="edit_cut" />
+ <Action name="edit_copy" />
+ <Action name="edit_paste" />
+ <Action name="edit_delete" />
+ <Separator/>
+ <Action name="view_zoom_in"/>
+ <Action name="view_zoom_out"/>
+ <Action name="view_zoom"/>
+ <Separator/>
+ </ToolBar>
+ <ToolBar noMerge="1" name="kImageMapEditorPartDrawToolBar">
+ <text>KImageMapEditor Draw Toolbar</text>
+ <Action name="tool_arrow" />
+ <Action name="tool_circle" />
+ <Action name="tool_rectangle" />
+ <Action name="tool_polygon" />
+ <Action name="tool_freehand" />
+ <Action name="tool_addpoint" />
+ <Action name="tool_removepoint" />
+ </ToolBar>
+ <Menu name="popup_main">
+ <Action name="edit_properties" />
+ <Separator/>
+ <Action name="edit_cut" />
+ <Action name="edit_copy" />
+ <Action name="edit_paste" />
+ <Action name="edit_delete" />
+ <Separator/>
+ <Action name="tofront" />
+ <Action name="toback" />
+ <Action name="forwardone" />
+ <Action name="backone" />
+ </Menu>
+ <Menu name="popup_map">
+ <Action name="map_name" />
+ <Action name="map_new" />
+ <Action name="map_delete" />
+ <Action name="map_defaultarea" />
+ </Menu>
+ <Menu name="popup_image">
+ <Action name="image_usemap" />
+ <Action name="image_remove" />
+ <Action name="image_add" />
+ </Menu>
+
+
+ <ActionProperties>
+ <Action shortcut="Left" name="moveleft" />
+ <Action shortcut="Right" name="moveright" />
+ <Action shortcut="Down" name="movedown" />
+ <Action shortcut="Up" name="moveup" />
+ <Action shortcut="Shift+Left" name="decreasewidth" />
+ <Action shortcut="Shift+Right" name="increasewidth" />
+ <Action shortcut="Shift+Down" name="decreaseheight" />
+ <Action shortcut="Shift+Up" name="increaseheight" />
+ <Action shortcut="Escape" name="canceldrawing" />
+
+ </ActionProperties>
+</kpartgui>
+
+
+
+
+
+
+
diff --git a/kimagemapeditor/kimagemapeditorui.rc b/kimagemapeditor/kimagemapeditorui.rc
new file mode 100644
index 00000000..68bb713a
--- /dev/null
+++ b/kimagemapeditor/kimagemapeditorui.rc
@@ -0,0 +1,25 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui name="kimagemapeditor" version="16">
+ <MenuBar>
+ <Menu name="file"><text>&amp;File</text>
+ <Merge/>
+ </Menu>
+ <Menu name="settings">
+ <DefineGroup name="settings_show" append="show_merge"/>
+ <DefineGroup name="settings_configure" append="configure_merge"/>
+ </Menu>
+ <Merge/>
+ </MenuBar>
+ <StatusBar/>
+ <ToolBar noMerge="1" name="mainToolBar">
+ <text>KImageMapEditor Main Toolbar</text>
+ <Action name="file_new" />
+ </ToolBar>
+</kpartgui>
+
+
+
+
+
+
+
diff --git a/kimagemapeditor/kimearea.cpp b/kimagemapeditor/kimearea.cpp
new file mode 100644
index 00000000..cb873564
--- /dev/null
+++ b/kimagemapeditor/kimearea.cpp
@@ -0,0 +1,1749 @@
+/***************************************************************************
+ kimearea.cpp - description
+ -------------------
+ begin : Thu Jun 14 2001
+ copyright : (C) 2001 by Jan Schaefer
+ email : janschaefer@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include <qbitmap.h>
+#include <qpointarray.h>
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qimage.h>
+#include <qpen.h>
+#include <qbrush.h>
+#include <qpalette.h>
+#include <qcolor.h>
+#include <qlistview.h>
+
+#include <kdebug.h>
+
+#include "kimearea.h"
+#include "kimecommon.h"
+
+
+#define SELSIZE 7
+
+
+bool Area::highlightArea;
+bool Area::showAlt;
+
+
+Area::Area()
+{
+ _coords=new QPointArray();
+ _selectionPoints= new SelectionPointList();
+ _selectionPoints->setAutoDelete(true);
+ _finished=false;
+ _isSelected=false;
+ _name=i18n("noname");
+ _listViewItem=0L;
+ currentHighlighted=-1;
+ _type=Area::None;
+ _highlightedPixmap=0L;
+
+}
+
+Area* Area::clone() const
+{
+ Area* areaClone = new Area();
+ areaClone->setArea( *this );
+ return areaClone;
+}
+
+QPointArray* Area::coords() const {
+ return _coords;
+}
+
+QString Area::getHTMLAttributes() const
+{
+ QString retStr="";
+
+ for (AttributeIterator it = firstAttribute();it!=lastAttribute();++it)
+ {
+ retStr+=it.key()+"=\""+it.data()+"\" ";
+ }
+
+ return retStr;
+}
+
+
+Area::~Area() {
+ delete _coords;
+ delete _selectionPoints;
+ delete _highlightedPixmap;
+
+}
+
+bool Area::contains(const QPoint &) const {
+ return false;
+}
+
+QString Area::getHTMLCode() const {
+ return "";
+}
+
+QString Area::attribute(const QString & name) const
+{
+ return _attributes[name.lower()];
+}
+
+void Area::setAttribute(const QString & name, const QString & value)
+{
+ _attributes.replace(name.lower(),value);
+ if (value.isEmpty())
+ _attributes.remove(name.lower());
+}
+
+AttributeIterator Area::firstAttribute() const
+{
+ return _attributes.begin();
+}
+
+AttributeIterator Area::lastAttribute() const
+{
+ return _attributes.end();
+}
+
+
+bool Area::setCoords(const QString &) {
+ return true;
+}
+
+void Area::moveSelectionPoint(QRect*, const QPoint &)
+{}
+
+
+ // Default implementation; is specified by subclasses
+QString Area::coordsToString() const
+{
+ return "";
+}
+
+
+Area::ShapeType Area::type() const {
+ return _type;
+}
+
+void Area::setArea(const Area & copy)
+{
+ delete _coords;
+ delete _selectionPoints;
+ _coords=new QPointArray(copy.coords()->copy());
+ _selectionPoints= new SelectionPointList();
+ currentHighlighted=-1;
+
+ // Need a deep copy of the list
+ for (QRect *r=copy.selectionPoints()->first();r!=0L;r=copy.selectionPoints()->next())
+ _selectionPoints->append(new QRect( r->topLeft(),r->bottomRight() ) );
+
+ _finished=copy.finished();
+ _isSelected=copy.isSelected();
+ _rect = copy.rect();
+
+ for (AttributeIterator it = copy.firstAttribute();it!=copy.lastAttribute();++it)
+ {
+ setAttribute(it.key(),it.data());
+ }
+
+ setMoving(copy.isMoving());
+
+// _listViewItem=0L;
+
+}
+
+void Area::setListViewItem(QListViewItem* item) {
+ _listViewItem=item;
+}
+
+void Area::deleteListViewItem()
+{
+ delete _listViewItem;
+ _listViewItem = 0L;
+}
+
+
+void Area::setRect(const QRect & r)
+{
+ _rect=r;
+ updateSelectionPoints();
+}
+
+QRect Area::rect() const {
+ return _rect;
+}
+
+void Area::setMoving(bool b) {
+ _isMoving=b;
+}
+
+
+void Area::moveBy(int dx, int dy) {
+ _rect.moveBy(dx,dy);
+ for (uint i=0;i<_coords->size();i++) {
+ int newX=_coords->point(i).x()+dx;
+ int newY=_coords->point(i).y()+dy;
+ _coords->setPoint(i,newX,newY);
+ }
+
+ for (QRect *r=_selectionPoints->first();r!=0L;r=_selectionPoints->next()) {
+ r->moveBy(dx,dy);
+ }
+}
+
+
+void Area::moveTo(int x, int y) {
+ int dx=x-rect().left();
+ int dy=y-rect().top();
+ moveBy(dx,dy);
+}
+
+uint Area::countSelectionPoints() const
+{
+ return (uint) selectionPoints()->count();
+}
+
+int Area::addCoord(const QPoint & p)
+{
+ _coords->resize(_coords->size()+1);
+ _coords->setPoint(_coords->size()-1,p);
+
+ QRect *r= new QRect(0,0,SELSIZE,SELSIZE);
+ r->moveCenter(p);
+ _selectionPoints->append(r);
+ setRect(_coords->boundingRect());
+
+ return _coords->size()-1;
+}
+
+void Area::insertCoord(int pos, const QPoint & p)
+{
+
+/*
+ kdDebug() << p.x() << "," << p.y() << endl;
+
+ if ( _coords->size()>0 )
+ {
+ for (int i=0; i<_coords->size(); i++)
+ {
+ if (p==_coords->point(i))
+ {
+ kdDebug() << "same Point already exists" << endl;
+ return;
+ }
+
+ }
+ }
+*/
+ _coords->resize(_coords->size()+1);
+
+
+ for (int i=_coords->size()-1;i>pos;i--) {
+ _coords->setPoint(i,_coords->point(i-1));
+ }
+ _coords->setPoint(pos, p);
+
+ QRect *r= new QRect(0,0,SELSIZE,SELSIZE);
+ r->moveCenter(p);
+ _selectionPoints->insert(pos,r);
+ setRect(_coords->boundingRect());
+}
+
+void Area::removeCoord(int pos) {
+
+ int count=_coords->size();
+
+ if (count<4)
+ {
+ kdDebug() << "Danger : trying to remove coordinate from Area with less then 4 coordinates !" << endl;
+ return;
+ }
+
+ for (int i=pos;i<(count-1);i++)
+ _coords->setPoint(i, _coords->point(i+1));
+
+ _coords->resize(count-1);
+ _selectionPoints->remove(pos);
+ setRect(_coords->boundingRect());
+}
+
+bool Area::removeSelectionPoint(QRect * r)
+{
+ if (_selectionPoints->contains(r))
+ {
+ removeCoord(_selectionPoints->find(r));
+ return true;
+ }
+
+ return false;
+}
+
+
+void Area::moveCoord(int pos, const QPoint & p) {
+ _coords->setPoint(pos,p);
+ _selectionPoints->at(pos)->moveCenter(p);
+ setRect(_coords->boundingRect());
+}
+
+void Area::setSelected(bool b)
+{
+ _isSelected=b;
+ if (_listViewItem) {
+ _listViewItem->setSelected(b);
+ }
+}
+
+void Area::highlightSelectionPoint(int number){
+ currentHighlighted=number;
+}
+
+QRect Area::selectionRect() const {
+ QRect r = rect();
+ r.moveBy(-SELSIZE*2,-SELSIZE*2);
+ r.setSize(r.size()+QSize(SELSIZE*4,SELSIZE*4));
+
+ return r;
+}
+
+void Area::drawHighlighting(QPainter & p)
+{
+ if (Area::highlightArea && !isMoving() && _highlightedPixmap)
+ {
+ p.setRasterOp(Qt::CopyROP);
+
+ QPoint point = QPoint(rect().x(),rect().y());
+ if (point.x()<0)
+ point.setX(0);
+ if (point.y()<0)
+ point.setY(0);
+
+ p.drawPixmap( point, *_highlightedPixmap);
+
+ }
+}
+
+void Area::drawAlt(QPainter & p)
+{
+ double x,y;
+
+ double scalex = p.worldMatrix().m11();
+// double scaley = p.worldMatrix().m12();
+
+ QWMatrix oldMatrix = p.worldMatrix();
+
+ p.setWorldMatrix(QWMatrix(1,oldMatrix.m12(), oldMatrix.m21(), 1, oldMatrix.dx(), oldMatrix.dy() ));
+
+ x = (rect().x()+rect().width()/2)*scalex;
+ y = (rect().y()+rect().height()/2)*scalex;
+
+ QFontMetrics metrics = p.fontMetrics();
+
+ int w = metrics.width(attribute("alt"));
+ x -= w/2;
+ y += metrics.height()/4;
+
+
+
+ if (highlightArea)
+ {
+ p.setRasterOp(Qt::CopyROP);
+ p.setPen(Qt::black);
+ }
+ else
+ {
+ p.setRasterOp(Qt::XorROP);
+ p.setPen(QPen(QColor("white"),1));
+ }
+
+ p.drawText(myround(x),myround(y),attribute("alt"));
+
+ p.setWorldMatrix(oldMatrix);
+}
+
+void Area::draw(QPainter & p)
+{
+
+ // Only draw the selection points at base class
+ // the rest is done in the derived classes
+ if (_isSelected)
+ {
+ int i=0;
+
+ double scalex = p.worldMatrix().m11();
+// double scaley = p.worldMatrix().m12();
+
+ QWMatrix oldMatrix = p.worldMatrix();
+
+ p.setWorldMatrix(QWMatrix(1,oldMatrix.m12(), oldMatrix.m21(), 1, oldMatrix.dx(), oldMatrix.dy() ));
+
+ for (QRect *r=_selectionPoints->first();r!=0L;r=_selectionPoints->next()) {
+
+ // Draw a green circle around the selected point ( only when editing a polygon )
+ if (i==currentHighlighted) {
+ QRect r2(0,0,15,15);
+ r2.moveCenter(r->center()*scalex);
+ p.setRasterOp(Qt::CopyROP);
+ p.setPen(QPen(QColor("lightgreen"),2));
+ p.drawEllipse(r2);
+ p.setRasterOp(Qt::XorROP);
+ p.setPen(QPen(QColor("white"),1));
+ }
+
+ // Draw the selection point
+ p.setRasterOp(Qt::XorROP);
+
+ QRect r3(*r);
+ int d = 1;
+ if (scalex > 2) d=0;
+
+ r3.moveCenter( QPoint((int)(r3.center().x()*scalex),(int)(r3.center().y()*scalex)) );
+
+ p.fillRect(r3,QBrush("white"));
+/*
+ QRect r3(*r);
+ r3.moveTopLeft( QPoint(r3.left()*scalex+2*(scalex-1), r3.top()*scalex+2*(scalex-1)) );
+
+ r3.setSize(r3.size()+QSize(2,2));
+//+ r3.moveBy(-1,-1);
+ p.setRasterOp(Qt::CopyROP);
+ p.setPen(QPen(QColor("lightgreen"),1));
+ p.setBrush(QColor("lightgreen"));
+ p.drawPie(r3,0,5760);
+ p.setPen(QPen(QColor("black"),1));
+ r3.setSize(r3.size()+QSize(2,2));
+ r3.moveBy(-1,-1);
+ p.drawEllipse(r3);
+*/
+ i++;
+ }
+ p.setWorldMatrix(oldMatrix);
+
+
+ }
+
+ if (showAlt)
+ {
+ drawAlt(p);
+ }
+ p.setRasterOp(Qt::XorROP);
+
+}
+
+QRect* Area::onSelectionPoint(const QPoint & p, double zoom) const
+{
+ for (QRect *r=_selectionPoints->first();r!=0L;r=_selectionPoints->next())
+ {
+ QRect r2(r->topLeft(),r->bottomRight());
+
+ r2.moveCenter(r2.center()*zoom);
+
+ if (r2.contains(p))
+ {
+
+ return r;
+ }
+ }
+
+ return 0L;
+}
+
+
+
+
+/**
+ * returns only the part of the image which is
+ * covered by the area
+ */
+QPixmap Area::cutOut(const QImage & image)
+{
+ if ( 0>=rect().width() ||
+ 0>=rect().height() ||
+ !rect().intersects(image.rect()) )
+ {
+ QPixmap dummyPix(10,10);
+ dummyPix.fill();
+ delete _highlightedPixmap;
+ _highlightedPixmap = 0L;
+ return dummyPix;
+ }
+
+ // Get the mask from the subclasses
+ QBitmap mask=getMask();
+
+ // The rectangle which is part of the image
+ QRect partOfImage=rect();
+ QRect partOfMask(0,0,mask.width(),mask.height());
+
+
+ // If the area is outside of the image make the
+ // preview smaller
+ if ( (rect().x()+rect().width()) > image.width() ) {
+ partOfImage.setWidth( image.width()-rect().x() );
+ partOfMask.setWidth( image.width()-rect().x() );
+ }
+
+ if ( (rect().x() < 0) ) {
+ partOfImage.setX(0);
+ partOfMask.setX(myabs(rect().x()));
+ }
+
+ if ( (rect().y()+rect().height()) > image.height() ) {
+ partOfImage.setHeight( image.height()-rect().y() );
+ partOfMask.setHeight ( image.height()-rect().y() );
+ }
+
+ if ( (rect().y() < 0) ) {
+ partOfImage.setY(0);
+ partOfMask.setY(myabs(rect().y()));
+ }
+
+ QImage tempImage=mask.convertToImage().copy(partOfMask);
+ mask.convertFromImage(tempImage);
+
+// partOfImage = partOfImage.normalize();
+ QImage cut=image.copy(partOfImage);
+
+ QPixmap pix;
+
+// partOfMask = partOfMask.normalize();
+ if (!partOfMask.isValid())
+ kdDebug() << "PartofMask not valid : " << partOfMask.x() << "," << partOfMask.y() << ","
+ << partOfMask.width() << "," << partOfMask.height() << "," << endl;
+
+/*
+ QBitmap mask2(partOfMask.width(), partOfMask.height());
+ QPainter p4(&mask2);
+ p4.drawPixmap( QPoint(0,0) ,mask,partOfMask);
+ p4.flush();
+ p4.end();
+*/
+
+ pix.convertFromImage(cut);
+
+ setHighlightedPixmap(cut, mask);
+
+ QPixmap retPix(pix.width(),pix.height());
+ QPainter p3(&retPix);
+
+ // if transparent image fill the background
+ // with gimp-like rectangles
+ if (pix.mask()) {
+ QPixmap backPix(32,32);
+
+ // Gimp like transparent rectangle
+ QPainter p2(&backPix);
+ p2.fillRect(0,0,32,32,QColor(156,149,156));
+ p2.fillRect(0,16,16,16,QColor(98,105,98));
+ p2.fillRect(16,0,16,16,QColor(98,105,98));
+ p2.flush();
+
+ p3.setPen(QPen());
+ p3.fillRect(0,0,pix.width(),pix.height(),QBrush(QColor("black"),backPix));
+ }
+
+
+ p3.drawPixmap(QPoint(0,0),pix);
+ p3.flush();
+ p3.end();
+ retPix.setMask(mask);
+
+ return retPix;
+}
+
+QBitmap Area::getMask() const
+{
+ QBitmap b;
+ return b;
+}
+
+void Area::setHighlightedPixmap( QImage & im, QBitmap & mask )
+{
+ if (!Area::highlightArea)
+ return;
+
+ delete _highlightedPixmap;
+
+ QImage image = im.convertDepth( 32 );
+ QSize size = image.size();
+ QColor pixel;
+ double r,g,b;
+
+
+ // highlight every pixel
+ for (int y=0; y < size.height(); y++)
+ {
+ for (int x=0; x < size.width(); x++)
+ {
+ r = qRed(image.pixel(x,y));
+ g = qGreen(image.pixel(x,y));
+ b = qBlue(image.pixel(x,y));
+ r = (r *123 / 255)+132;
+ g = (g *123 / 255)+132;
+ b = (b *123 / 255)+132;
+
+ pixel.setRgb( (int) r, (int) g, (int) b);
+ image.setPixel(x,y, pixel.rgb());
+ }
+ }
+
+ _highlightedPixmap = new QPixmap();
+ _highlightedPixmap->convertFromImage( image );
+ _highlightedPixmap->setMask( mask );
+
+ if (_highlightedPixmap->isNull())
+ kdDebug() << "HighlightedPixmap is null" << endl;
+
+}
+
+/********************************************************************
+ * RECTANGLE
+ *******************************************************************/
+
+
+RectArea::RectArea()
+ : Area()
+{
+ QRect *p = new QRect(0,0,SELSIZE,SELSIZE);
+ _selectionPoints->append(p);
+ p = new QRect(0,0,SELSIZE,SELSIZE);
+ _selectionPoints->append(p);
+ p = new QRect(0,0,SELSIZE,SELSIZE);
+ _selectionPoints->append(p);
+ p = new QRect(0,0,SELSIZE,SELSIZE);
+ _selectionPoints->append(p);
+ _type=Area::Rectangle;
+
+}
+
+RectArea::~RectArea() {
+}
+
+Area* RectArea::clone() const
+{
+ Area* areaClone = new RectArea();
+ areaClone->setArea( *this );
+ return areaClone;
+}
+
+void RectArea::draw(QPainter & p)
+{
+
+ drawHighlighting(p);
+// p.setRasterOp(Qt::CopyROP);
+// p.setRasterOp(Qt:: OrROP);
+// QBrush b(QBrush::SolidPattern);
+// QBrush b(QBrush::Dense4Pattern);
+// QBrush b(QBrush::BDiagPattern);
+// b.setColor(QColor(32,32,32));
+// p.fillRect(rect(), b);
+
+ p.setRasterOp(Qt::XorROP);
+ p.setPen(QPen(QColor("white"),1));
+ QRect r(rect());
+ r.setWidth(r.width()+1);
+ r.setHeight(r.height()+1);
+ p.drawRect(r);
+
+ Area::draw(p);
+}
+
+QBitmap RectArea::getMask() const
+{
+ QBitmap mask(rect().width(),rect().height());
+
+ mask.fill(Qt::color0);
+ QPainter p(&mask);
+ p.setBackgroundColor(Qt::color0);
+ p.setPen(Qt::color1);
+ p.setBrush(Qt::color1);
+ mask.fill(Qt::color1);
+ p.end();
+
+ return mask;
+}
+
+QString RectArea::coordsToString() const
+{
+ QString retStr=QString("%1,%2,%3,%4")
+ .arg(rect().left())
+ .arg(rect().top())
+ .arg(rect().right())
+ .arg(rect().bottom());
+
+ return retStr;
+}
+
+bool RectArea::contains(const QPoint & p) const{
+ return rect().contains(p);
+}
+
+void RectArea::moveSelectionPoint(QRect* selectionPoint, const QPoint & p)
+{
+ selectionPoint->moveCenter(p);
+ int i=0;
+ for (QRect *r=_selectionPoints->first();r!=0L;r=_selectionPoints->next()) {
+ if (r==selectionPoint)
+ break;
+ i++;
+ }
+ QRect r2(_rect);
+ switch (i) {
+ case 0 : _rect.setLeft(p.x());
+ _rect.setTop(p.y());
+ break;
+ case 1 : _rect.setRight(p.x());
+ _rect.setTop(p.y());
+ break;
+ case 2 : _rect.setLeft(p.x());
+ _rect.setBottom(p.y());
+ break;
+ case 3 : _rect.setRight(p.x());
+ _rect.setBottom(p.y());
+ break;
+ }
+ if ( ! _rect.isValid())
+ _rect=r2;
+
+ updateSelectionPoints();
+}
+
+void RectArea::updateSelectionPoints()
+{
+ _selectionPoints->first()->moveCenter(_rect.topLeft());
+ _selectionPoints->next()->moveCenter(_rect.topRight()+QPoint(1,0));
+ _selectionPoints->next()->moveCenter(_rect.bottomLeft()+QPoint(0,1));
+ _selectionPoints->next()->moveCenter(_rect.bottomRight()+QPoint(1,1));
+}
+
+bool RectArea::setCoords(const QString & s)
+{
+ _finished=true;
+
+ QStringList list=QStringList::split(",",s);
+ QRect r;
+ bool ok=true;
+ QStringList::Iterator it = list.begin();
+ r.setLeft((*it).toInt(&ok,10));it++;
+ r.setTop((*it).toInt(&ok,10));it++;
+ r.setRight((*it).toInt(&ok,10));it++;
+ r.setBottom((*it).toInt(&ok,10));
+ if (ok) {
+ setRect(r);
+ return true;
+ } else
+ return false;
+}
+
+QString RectArea::getHTMLCode() const {
+ QString retStr;
+ retStr+="<area ";
+ retStr+="shape=\"rect\" ";
+
+ retStr+=getHTMLAttributes();
+
+ retStr+="coords=\""+coordsToString()+"\" ";
+ retStr+="/>";
+ return retStr;
+
+}
+
+/********************************************************************
+ * CIRCLE
+ *******************************************************************/
+
+
+CircleArea::CircleArea()
+ : Area()
+{
+ _type=Area::Circle;
+ QRect *p = new QRect(0,0,SELSIZE,SELSIZE);
+ _selectionPoints->append(p);
+ p = new QRect(0,0,SELSIZE,SELSIZE);
+ _selectionPoints->append(p);
+ p = new QRect(0,0,SELSIZE,SELSIZE);
+ _selectionPoints->append(p);
+ p = new QRect(0,0,SELSIZE,SELSIZE);
+ _selectionPoints->append(p);
+}
+
+CircleArea::~CircleArea() {
+}
+
+Area* CircleArea::clone() const
+{
+ Area* areaClone = new CircleArea();
+ areaClone->setArea( *this );
+ return areaClone;
+}
+
+void CircleArea::draw(QPainter & p)
+{
+ drawHighlighting(p);
+
+/*
+ p.setRasterOp(Qt::CopyROP);
+ QBrush bold = p.brush();
+ QBrush b(QBrush::Dense5Pattern);
+ b.setColor(QColor("green"));
+ p.setBrush(b);
+ QRect r = _rect;
+ r.moveBy(1,1);
+ r.setSize( r.size()-QSize(2,2) );
+ p.drawChord(r,0,5760);
+ p.setBrush(bold);
+*/
+ p.setRasterOp(Qt::XorROP);
+ p.setPen(QPen(QColor("white"),1));
+
+ QRect r(_rect);
+ r.setWidth(r.width()+1);
+ r.setHeight(r.height()+1);
+ p.drawEllipse(r);
+
+ Area::draw(p);
+}
+
+QBitmap CircleArea::getMask() const
+{
+ QBitmap mask(_rect.width(),_rect.height());
+
+ mask.fill(Qt::color0);
+ QPainter p(&mask);
+ p.setBackgroundColor(Qt::color0);
+ p.setPen(Qt::color1);
+ p.setBrush(Qt::color1);
+ p.drawPie(QRect(0,0,_rect.width(),_rect.height()),0,5760);
+ p.flush();
+ p.end();
+
+
+ return mask;
+
+}
+
+QString CircleArea::coordsToString() const
+{
+ QString retStr=QString("%1,%2,%3")
+ .arg(_rect.center().x())
+ .arg(_rect.center().y())
+ .arg(_rect.width()/2);
+
+ return retStr;
+}
+
+bool CircleArea::contains(const QPoint & p) const
+{
+ QRegion r(_rect,QRegion::Ellipse);
+ return r.contains(p);
+}
+
+void CircleArea::moveSelectionPoint(QRect* selectionPoint, const QPoint & p)
+{
+ selectionPoint->moveCenter(p);
+
+ int i=0;
+ for (QRect *r=_selectionPoints->first();r!=0L;r=_selectionPoints->next()) {
+ if (r==selectionPoint)
+ break;
+ i++;
+ }
+
+ // The code below really sucks, but I have no better idea.
+ // it only makes sure that the circle is perfektly round
+ QPoint newPoint;
+ int diff=myabs(p.x()-_rect.center().x());
+ if (myabs(p.y()-_rect.center().y())>diff)
+ diff=myabs(p.y()-_rect.center().y());
+
+ newPoint.setX( p.x()-_rect.center().x()<0
+ ? _rect.center().x()-diff
+ : _rect.center().x()+diff);
+
+ newPoint.setY( p.y()-_rect.center().y()<0
+ ? _rect.center().y()-diff
+ : _rect.center().y()+diff);
+
+ switch (i) {
+ case 0 : if (newPoint.x() < _rect.center().x() &&
+ newPoint.y() < _rect.center().y())
+ {
+ _rect.setLeft(newPoint.x());
+ _rect.setTop(newPoint.y());
+ }
+ break;
+ case 1 : if (newPoint.x() > _rect.center().x() &&
+ newPoint.y() < _rect.center().y())
+ {
+ _rect.setRight(newPoint.x());
+ _rect.setTop(newPoint.y());
+ }
+ break;
+ case 2 : if (newPoint.x() < _rect.center().x() &&
+ newPoint.y() > _rect.center().y())
+ {
+ _rect.setLeft(newPoint.x());
+ _rect.setBottom(newPoint.y());
+ }
+ break;
+ case 3 : if (newPoint.x() > _rect.center().x() &&
+ newPoint.y() > _rect.center().y())
+ {
+ _rect.setRight(newPoint.x());
+ _rect.setBottom(newPoint.y());
+ }
+ break;
+ }
+
+
+
+ updateSelectionPoints();
+
+}
+
+void CircleArea::setRect(const QRect & r)
+{
+ QRect r2 = r;
+ if ( r2.height() != r2.width() )
+ r2.setHeight( r2.width() );
+
+ Area::setRect(r2);
+}
+
+
+void CircleArea::updateSelectionPoints()
+{
+ _selectionPoints->first()->moveCenter(_rect.topLeft());
+ _selectionPoints->next()->moveCenter(_rect.topRight());
+ _selectionPoints->next()->moveCenter(_rect.bottomLeft());
+ _selectionPoints->next()->moveCenter(_rect.bottomRight());
+}
+
+bool CircleArea::setCoords(const QString & s)
+{
+ _finished=true;
+ QStringList list=QStringList::split(",",s);
+ bool ok=true;
+ QStringList::Iterator it = list.begin();
+ int x=(*it).toInt(&ok,10);it++;
+ int y=(*it).toInt(&ok,10);it++;
+ int rad=(*it).toInt(&ok,10);
+ if (!ok) return false;
+ QRect r;
+ r.setWidth(rad*2);
+ r.setHeight(rad*2);
+ r.moveCenter(QPoint(x,y));
+ setRect(r);
+ return true;
+}
+
+QString CircleArea::getHTMLCode() const {
+ QString retStr;
+ retStr+="<area ";
+ retStr+="shape=\"circle\" ";
+
+ retStr+=getHTMLAttributes();
+
+ retStr+="coords=\""+coordsToString()+"\" ";
+ retStr+="/>";
+ return retStr;
+
+}
+
+
+/********************************************************************
+ * POLYGON
+ *******************************************************************/
+
+
+PolyArea::PolyArea()
+ : Area()
+{
+ _type=Area::Polygon;
+}
+
+PolyArea::~PolyArea() {
+}
+
+Area* PolyArea::clone() const
+{
+ Area* areaClone = new PolyArea();
+ areaClone->setArea( *this );
+ return areaClone;
+}
+
+void PolyArea::draw(QPainter & p)
+{
+ drawHighlighting(p);
+
+ p.setRasterOp(Qt::XorROP);
+ p.setPen(QPen(QColor("white"),1));
+ if (_coords->count()==0) return;
+
+
+
+ if (_finished)
+ p.drawPolygon ( *_coords,false,0,_coords->count());
+ else
+ p.drawPolyline ( *_coords,0,_coords->count());
+
+/*
+ p.moveTo(_coords->point(0));
+ for (int i=1;i<_coords->count();i++)
+ p.lineTo(_coords->point(i));
+
+ if (_finished)
+ p.lineTo(_coords->point(0));
+*/
+ Area::draw(p);
+}
+
+QBitmap PolyArea::getMask() const
+{
+ QBitmap mask(_rect.width(),_rect.height());
+
+ mask.fill(Qt::color0);
+ QPainter p(&mask);
+ p.setBackgroundColor(Qt::color0);
+ p.setPen(Qt::color1);
+ p.setBrush(Qt::color1);
+ p.setClipping(true);
+ QRegion r(*_coords);
+ r.translate(-_rect.left(),-_rect.top());
+ p.setClipRegion(r);
+ p.fillRect(QRect(0,0,_rect.width(),_rect.height()),Qt::color1);
+ p.flush();
+ p.end();
+
+ return mask;
+}
+
+QString PolyArea::coordsToString() const
+{
+ QString retStr;
+
+ for (uint i=0;i<_coords->count();i++) {
+ retStr.append(QString("%1,%2,")
+ .arg(_coords->point(i).x())
+ .arg(_coords->point(i).y()));
+ }
+
+ retStr.remove(retStr.length()-1,1);
+
+ return retStr;
+}
+
+int PolyArea::distance(const QPoint &p1, const QPoint &p2)
+{
+ QPoint temp = p1-p2;
+ return temp.manhattanLength();
+}
+
+bool PolyArea::isBetween(const QPoint &p, const QPoint &p1, const QPoint &p2)
+{
+ int dist = distance(p,p1)+distance(p,p2)-distance(p1,p2);
+
+ if (myabs(dist)<1)
+ return true;
+ else
+ return false;
+}
+
+void PolyArea::simplifyCoords()
+{
+ if (_coords->size()<4)
+ return;
+
+ QPoint p = _coords->point(0) - _coords->point(1);
+
+ uint i = 1;
+
+
+ while( (i<_coords->size()) && (_coords->size() > 3) )
+ {
+ p = _coords->point(i-1) - _coords->point(i);
+
+ if (p.manhattanLength() < 3)
+ removeCoord(i);
+ else
+ i++;
+ }
+
+ p = _coords->point(0) - _coords->point(1);
+
+ double angle2;
+ double angle1;
+
+ if (p.y()==0)
+ angle1 = 1000000000;
+ else
+ angle1 = (double) p.x() / (double) p.y();
+
+ i=2;
+
+ while( (i<_coords->size()) && (_coords->size() > 3) )
+ {
+ p = _coords->point(i-1) - _coords->point(i);
+
+ if (p.y()==0)
+ angle2 = 1000000000;
+ else
+ angle2 = (double) p.x() / (double) p.y();
+
+ if ( angle2==angle1 )
+ {
+ kdDebug() << "removing " << i-1 << endl;
+ removeCoord(i-1);
+ }
+ else
+ {
+ i++;
+ kdDebug() << "skipping " << i-1 << " cause " << angle1 << "!= " << angle2 << endl;
+ angle1 = angle2;
+
+ }
+
+ }
+
+
+
+}
+
+
+int PolyArea::addCoord(const QPoint & p)
+{
+ if (_coords->size()<3)
+ {
+ return Area::addCoord(p);
+ }
+
+ if (_coords->point(_coords->size()-1) == p)
+ {
+ kdDebug() << "equal Point added" << endl;
+ return -1;
+
+ }
+
+ int n=_coords->size();
+
+// QPoint temp = p-_coords->point(0);
+ int nearest = 0;
+ int olddist = distance(p,_coords->point(0));
+ int mindiff = 999999999;
+
+ // find the two points, which are the nearest one to the new point
+ for (int i=1; i <= n; i++)
+ {
+ int dist = distance(p,_coords->point(i%n));
+ int dist2 = distance(_coords->point(i-1),_coords->point(i%n));
+ int diff = myabs(dist+olddist-dist2);
+ if ( diff<mindiff )
+ {
+ mindiff = diff;
+ nearest = i%n;
+ }
+ olddist=dist;
+ }
+
+ insertCoord(nearest, p);
+
+ return nearest;
+
+}
+
+bool PolyArea::contains(const QPoint & p) const
+{
+ // A line can't contain a point
+ if (_coords->count() >2 ) {
+ QRegion r(*_coords);
+ return r.contains(p);
+ }
+ else
+ return false;
+}
+
+void PolyArea::moveSelectionPoint(QRect* selectionPoint, const QPoint & p)
+{
+ selectionPoint->moveCenter(p);
+
+ int i=0;
+ for (QRect *r=_selectionPoints->first();r!=0L;r=_selectionPoints->next()) {
+ if (r==selectionPoint)
+ break;
+ i++;
+ }
+ _coords->setPoint(i,p);
+ _rect=_coords->boundingRect();
+}
+
+void PolyArea::updateSelectionPoints()
+{
+ QRect *r;
+ r=_selectionPoints->first();
+
+ for (uint i=0;i<_coords->size();i++)
+ {
+ r->moveCenter(_coords->point(i));
+ r=_selectionPoints->next();
+ }
+
+}
+
+bool PolyArea::setCoords(const QString & s)
+{
+ _finished=true;
+ QStringList list=QStringList::split(",",s);
+ _coords=new QPointArray();
+ _selectionPoints= new SelectionPointList();
+
+ for (QStringList::Iterator it = list.begin(); it !=list.end(); ++it)
+ {
+ bool ok=true;
+ int newXCoord=(*it).toInt(&ok,10);
+ if (!ok) return false;
+ it++;
+ if (it==list.end()) break;
+ int newYCoord=(*it).toInt(&ok,10);
+ if (!ok) return false;
+ insertCoord(_coords->size(), QPoint(newXCoord,newYCoord));
+ }
+
+ return true;
+
+}
+
+QString PolyArea::getHTMLCode() const {
+ QString retStr;
+ retStr+="<area ";
+ retStr+="shape=\"poly\" ";
+
+ retStr+=getHTMLAttributes();
+
+ retStr+="coords=\""+coordsToString()+"\" ";
+ retStr+="/>";
+ return retStr;
+
+}
+
+void PolyArea::setFinished(bool b)
+{
+ // The last Point is the same as the first
+ // so delete it
+ _coords->resize(_coords->size()-1);
+ _selectionPoints->removeLast();
+ _finished=b;
+}
+
+QRect PolyArea::selectionRect() const
+{
+ QRect r = _rect;
+
+ r.moveBy(-10,-10);
+ r.setSize(r.size()+QSize(21,21));
+
+ return r;
+}
+
+
+
+/********************************************************************
+ * DEFAULT
+ *******************************************************************/
+
+
+DefaultArea::DefaultArea()
+ : Area()
+{
+ _type=Area::Default;
+}
+
+DefaultArea::~DefaultArea() {
+}
+
+Area* DefaultArea::clone() const
+{
+ Area* areaClone = new DefaultArea();
+ areaClone->setArea( *this );
+ return areaClone;
+}
+
+void DefaultArea::draw(QPainter &)
+{}
+
+
+QString DefaultArea::getHTMLCode() const {
+ QString retStr;
+ retStr+="<area ";
+ retStr+="shape=\"default\" ";
+
+ retStr+=getHTMLAttributes();
+
+ retStr+="/>";
+ return retStr;
+
+}
+
+
+/********************************************************************
+ * AreaSelection
+ *******************************************************************/
+
+AreaSelection::AreaSelection()
+ : Area()
+{
+ _areas = new AreaList();
+ _name = "Selection";
+ invalidate();
+}
+
+AreaSelection::~AreaSelection() {
+ delete _areas;
+}
+
+Area* AreaSelection::clone() const
+{
+ AreaSelection* areaClone = new AreaSelection();
+
+ // we want a deep copy of the Areas
+ AreaListIterator it=getAreaListIterator();
+
+ for ( ; it.current() != 0L; ++it )
+ {
+ areaClone->add( it.current()->clone() );
+ }
+
+// areaClone->setArea( *this );
+
+ return areaClone;
+}
+
+
+void AreaSelection::add(Area *a)
+{
+
+ // if a selection of areas was added get the areas of it
+ AreaSelection *selection=0L;
+ if ( (selection = dynamic_cast <AreaSelection*> ( a ) ) )
+ {
+ AreaList list = selection->getAreaList();
+
+ for (Area* area = list.first(); area != 0L; area = list.next() )
+ {
+ if ( _areas->find( area ) == -1 ) {
+ _areas->append( area ); // Must come before area->setSelected
+ area->setSelected( true );
+ }
+ }
+ }
+ else
+ {
+ if ( _areas->find( a ) == -1 ) {
+ _areas->append( a ); // Must come before a->setSelected
+ a->setSelected( true );
+ }
+ }
+
+ invalidate();
+}
+
+void AreaSelection::remove(Area *a)
+{
+ if (_areas->find(a) == -1)
+ return;
+
+ a->setSelected( false );
+ _areas->remove( a );
+ invalidate();
+}
+
+void AreaSelection::reset()
+{
+ AreaListIterator it=getAreaListIterator();
+
+ for ( ; it.current() != 0L; ++it )
+ {
+ it.current()->setSelected( false );
+ }
+
+ _areas->clear();
+ invalidate();
+}
+
+bool AreaSelection::contains(const QPoint & p) const
+{
+ bool b=false;
+ AreaListIterator it=getAreaListIterator();
+
+ for ( ; it.current() != 0L; ++it )
+ {
+ if ( it.current()->contains( p ) )
+ {
+ b=true;
+ break;
+ }
+ }
+
+ return b;
+}
+
+QRect* AreaSelection::onSelectionPoint(const QPoint & p, double zoom) const
+{
+ AreaListIterator it=getAreaListIterator();
+
+ if (it.count() != 1)
+ return 0L;
+
+ QRect* retRect=0L;
+
+ for ( ; it.current() != 0L; ++it )
+ {
+ if ( (retRect = it.current()->onSelectionPoint( p , zoom) ) )
+ {
+ break;
+ }
+ }
+
+ return retRect;
+}
+
+void AreaSelection::moveSelectionPoint(QRect* selectionPoint, const QPoint & p)
+{
+ // It's only possible to move a SelectionPoint if only one Area is selected
+ if (_areas->count() != 1)
+ return;
+
+ _areas->getFirst()->moveSelectionPoint(selectionPoint,p);
+
+ invalidate();
+}
+
+
+void AreaSelection::moveBy(int dx, int dy)
+{
+ AreaListIterator it=getAreaListIterator();
+
+ for ( ; it.current() != 0L; ++it )
+ it.current()->moveBy(dx,dy);
+
+ Area::moveBy( dx, dy );
+
+ invalidate();
+}
+
+QString AreaSelection::typeString() const
+{
+ // if there is only one Area selected
+ // show the name of that Area
+ if ( _areas->count()==0 )
+ return "";
+ else if ( _areas->count()==1 )
+ return _areas->getFirst()->typeString();
+ else
+ return i18n("Number of Areas");
+
+}
+
+Area::ShapeType AreaSelection::type() const
+{
+ // if there is only one Area selected
+ // take the type of that Area
+ if ( _areas->count()==0 )
+ return Area::None;
+ else if ( _areas->count()==1 )
+ return _areas->getFirst()->type();
+ else
+ return Area::Selection;
+}
+
+void AreaSelection::updateSelectionPoints()
+{
+
+ AreaListIterator it=getAreaListIterator();
+
+ for ( ; it.current() != 0L; ++it )
+ {
+ it.current()->updateSelectionPoints();
+ }
+
+ invalidate();
+
+}
+
+
+
+QRect AreaSelection::selectionRect() const
+{
+ if (!_selectionCacheValid)
+ {
+ _selectionCacheValid=true;
+ QRect r;
+ AreaListIterator it=getAreaListIterator();
+
+ for ( ; it.current() != 0L; ++it )
+ r = r | it.current()->selectionRect();
+
+ _cachedSelectionRect=r;
+ }
+
+ return _cachedSelectionRect;
+}
+
+uint AreaSelection::count() const {
+ return _areas->count();
+}
+
+bool AreaSelection::isEmpty() const
+{
+ return _areas->isEmpty();
+}
+
+
+AreaList AreaSelection::getAreaList() const {
+ AreaList list(*_areas);
+ return list;
+}
+
+AreaListIterator AreaSelection::getAreaListIterator() const {
+ AreaListIterator it(*_areas);
+ return it;
+}
+
+void AreaSelection::setArea(const Area & copy)
+{
+ Area *area = copy.clone();
+ AreaSelection *selection = dynamic_cast<AreaSelection*>(area);
+ if (selection)
+ setAreaSelection(*selection);
+ else {
+ Area::setArea(copy);
+ invalidate();
+ }
+}
+
+void AreaSelection::setAreaSelection(const AreaSelection & copy)
+{
+ AreaListIterator it=getAreaListIterator();
+ AreaListIterator it2=copy.getAreaListIterator();
+
+ if (it.count() != it2.count())
+ return;
+
+ for ( ; it.current() != 0L; ++it, ++it2 )
+ it.current()->setArea(*it2.current());
+
+ Area::setArea(copy);
+ invalidate();
+}
+
+void AreaSelection::setAreaList( const AreaList & areas )
+{
+ delete _areas;
+ _areas = new AreaList(areas);
+ invalidate();
+}
+
+void AreaSelection::setRect(const QRect & r)
+{
+ if ( _areas->count()==1 )
+ {
+ _areas->getFirst()->setRect(r);
+ }
+
+ invalidate();
+ _rect=rect();
+ updateSelectionPoints();
+}
+
+QRect AreaSelection::rect() const
+{
+ if (!_rectCacheValid)
+ {
+ _rectCacheValid=true;
+ QRect r;
+ AreaListIterator it=getAreaListIterator();
+
+ for ( ; it.current() != 0L; ++it )
+ r = r | it.current()->rect();
+
+ _cachedRect=r;
+ }
+
+ return _cachedRect;
+}
+
+
+int AreaSelection::addCoord(const QPoint & p)
+{
+ if ( _areas->count()==1 )
+ {
+ return _areas->getFirst()->addCoord(p);
+ invalidate();
+ }
+
+ return 0;
+}
+
+void AreaSelection::insertCoord(int pos, const QPoint & p)
+{
+ if ( _areas->count()==1 )
+ {
+ _areas->getFirst()->insertCoord(pos, p);
+ invalidate();
+ }
+}
+
+void AreaSelection::removeCoord(int pos)
+{
+ if ( _areas->count()==1 )
+ {
+ _areas->getFirst()->removeCoord(pos);
+ invalidate();
+ }
+}
+
+bool AreaSelection::removeSelectionPoint(QRect * r)
+{
+ bool result=false;
+
+ if ( _areas->count()==1 )
+ {
+ result = _areas->getFirst()->removeSelectionPoint(r);
+ invalidate();
+ }
+
+ return result;
+}
+
+SelectionPointList* AreaSelection::selectionPoints() const
+{
+ if ( _areas->count()==1 )
+ {
+ return _areas->getFirst()->selectionPoints();
+ }
+
+ return _selectionPoints;
+}
+
+
+void AreaSelection::moveCoord(int pos,const QPoint & p)
+{
+ if ( _areas->count()==1 )
+ {
+ _areas->getFirst()->moveCoord(pos,p);
+ invalidate();
+ }
+}
+
+void AreaSelection::highlightSelectionPoint(int i)
+{
+ if ( _areas->count()==1 )
+ {
+ _areas->getFirst()->highlightSelectionPoint(i);
+ invalidate();
+ }
+}
+
+
+QPointArray* AreaSelection::coords() const
+{
+ if ( _areas->count()==1 )
+ {
+ return _areas->getFirst()->coords();
+ }
+
+ return Area::coords();
+}
+
+QString AreaSelection::attribute(const QString & name) const
+{
+ if ( _areas->count()==1 )
+ {
+ return _areas->getFirst()->attribute(name);
+ }
+
+ return Area::attribute(name);
+}
+
+void AreaSelection::setAttribute(const QString & name, const QString & value)
+{
+ AreaListIterator it=getAreaListIterator();
+
+ for ( ; it.current() != 0L; ++it )
+ it.current()->setAttribute(name,value);
+
+ Area::setAttribute(name,value);
+}
+
+AttributeIterator AreaSelection::firstAttribute() const
+{
+ if ( _areas->count()==1 )
+ {
+ return _areas->getFirst()->firstAttribute();
+ }
+
+ return _attributes.begin();
+}
+
+AttributeIterator AreaSelection::lastAttribute() const
+{
+ if ( _areas->count()==1 )
+ {
+ return _areas->getFirst()->lastAttribute();
+ }
+
+ return _attributes.end();
+}
+
+void AreaSelection::setMoving(bool b)
+{
+ AreaListIterator it=getAreaListIterator();
+
+ for ( ; it.current() != 0L; ++it )
+ it.current()->setMoving(b);
+
+ Area::setMoving(b);
+}
+
+bool AreaSelection::isMoving() const
+{
+ if ( _areas->count()==1 )
+ {
+ return _areas->getFirst()->isMoving();
+ }
+
+ return Area::isMoving();
+}
+
+
+/**
+ * Checks if an area is outside the rectangle parameter
+ * returns false if an area has no pixel in common with the rectangle parameter
+ **/
+bool AreaSelection::allAreasWithin(const QRect & r) const
+{
+ if ( ! r.contains(rect()) )
+ {
+ AreaListIterator it=getAreaListIterator();
+
+ for ( ; it.current() != 0L; ++it )
+ if (!it.current()->rect().intersects(r))
+ return false;
+ }
+
+ return true;
+}
+
+
+void AreaSelection::draw(QPainter &)
+{}
+
+
diff --git a/kimagemapeditor/kimearea.h b/kimagemapeditor/kimearea.h
new file mode 100644
index 00000000..581bba94
--- /dev/null
+++ b/kimagemapeditor/kimearea.h
@@ -0,0 +1,392 @@
+/***************************************************************************
+ kimearea.h - description
+ -------------------
+ begin : Thu Jun 14 2001
+ copyright : (C) 2001 by Jan Schäfer
+ email : janschaefer@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef KIMEAREA_H
+#define KIMEAREA_H
+
+#include <qrect.h>
+#include <qpoint.h>
+#include <qptrlist.h>
+#include <klocale.h>
+#include <qmap.h>
+
+#include "kdeversion.h"
+
+class QPainter;
+class QPointArray;
+class QListViewItem;
+class QBitmap;
+
+typedef QPtrList<QRect> SelectionPointList;
+
+typedef QMap<QString,QString> AttributeMap;
+typedef QMapConstIterator<QString,QString> AttributeIterator;
+
+
+
+class Area
+{
+public:
+ enum ShapeType { None, Rectangle, Circle, Polygon, Default, Selection };
+ static bool highlightArea;
+ static bool showAlt;
+
+protected:
+ QRect _rect;
+ ShapeType _type;
+ QString _name;
+ QString _href;
+ QString _alt;
+ QString _target;
+ AttributeMap _attributes;
+ bool _isSelected;
+ bool _finished;
+ bool _isMoving;
+ int currentHighlighted;
+ QListViewItem* _listViewItem;
+ // Only used for Polygons
+ QPointArray *_coords;
+ SelectionPointList *_selectionPoints;
+ QPixmap *_highlightedPixmap;
+
+ void drawHighlighting(QPainter & p);
+ void drawAlt(QPainter & p);
+ QString getHTMLAttributes() const;
+
+public:
+ Area();
+ virtual ~Area();
+
+ virtual Area* clone() const;
+ // Default implementation; is specified by subclasses
+ virtual bool contains(const QPoint &) const;
+ // Default implementation; is specified by subclasses
+ virtual QString coordsToString() const;
+ virtual void draw(QPainter &);
+
+ virtual QBitmap getMask() const;
+ virtual QString getHTMLCode() const;
+
+ virtual void setHighlightedPixmap( QImage &, QBitmap &);
+
+ virtual void moveBy(int, int);
+ virtual void moveTo(int, int);
+ virtual void moveSelectionPoint(QRect*, const QPoint &);
+
+ virtual QRect* onSelectionPoint(const QPoint &,double zoom) const;
+ virtual bool removeSelectionPoint(QRect * r);
+ virtual SelectionPointList* selectionPoints() const { return _selectionPoints; }
+
+ virtual QRect rect() const;
+
+ virtual QRect selectionRect() const;
+ virtual void setArea(const Area &);
+ virtual bool setCoords(const QString &);
+ /** finished drawing only important for polygon */
+ virtual void setFinished(bool b) { _finished=b; }
+ virtual void setRect(const QRect &);
+ virtual void setMoving(bool b);
+ virtual bool isMoving() const;
+ // Default implementation; is specified by subclasses
+ virtual QString typeString() const { return ""; }
+ virtual ShapeType type() const;
+
+ virtual void updateSelectionPoints() {};
+
+ // Only interesting for Polygons
+ virtual void simplifyCoords() {};
+ virtual int addCoord(const QPoint &);
+ virtual void insertCoord(int, const QPoint &);
+ virtual void removeCoord(int);
+ virtual void moveCoord(int,const QPoint &);
+ virtual QPointArray* coords() const;
+ virtual void highlightSelectionPoint(int);
+
+ virtual QString attribute(const QString &) const;
+ virtual void setAttribute(const QString &, const QString &);
+ virtual AttributeIterator firstAttribute() const;
+ virtual AttributeIterator lastAttribute() const;
+
+ QPixmap cutOut(const QImage &) ;
+ void setListViewItem(QListViewItem*);
+ void deleteListViewItem();
+ QListViewItem* listViewItem() const;
+ void setName(const QString &);
+ QString name() const;
+ void setSelected(bool b);
+ bool isSelected() const;
+ bool finished() const;
+ uint countSelectionPoints() const;
+
+};
+
+
+
+inline QListViewItem* Area::listViewItem() const {
+ return _listViewItem;
+}
+
+inline void Area::setName(const QString & name) {
+ _name=name;
+}
+
+inline QString Area::name() const {
+ return _name;
+}
+
+inline bool Area::isMoving() const {
+ return _isMoving;
+}
+
+
+inline bool Area::isSelected() const {
+ return _isSelected;
+}
+
+
+inline bool Area::finished() const {
+ return _finished;
+}
+
+/**
+ * Represents a Rectangle Area
+ **/
+class RectArea : public Area
+{
+ public:
+ RectArea();
+ virtual ~RectArea();
+
+ virtual Area* clone() const;
+ virtual bool contains(const QPoint & p) const;
+ virtual QString coordsToString() const;
+ virtual void draw(QPainter & p);
+ virtual void moveSelectionPoint(QRect* selectionPoint, const QPoint & p);
+ virtual bool setCoords(const QString & s);
+ virtual QString typeString() const { return i18n("Rectangle"); }
+ virtual QBitmap getMask() const;
+ virtual QString getHTMLCode() const;
+ virtual void updateSelectionPoints();
+};
+
+
+/**
+ * Represents a Circle Area
+ **/
+class CircleArea : public Area
+{
+ public:
+ CircleArea();
+ virtual ~CircleArea();
+
+ virtual Area* clone() const;
+ virtual bool contains(const QPoint & p) const;
+ virtual QString coordsToString() const;
+ virtual void draw(QPainter & p);
+ virtual void moveSelectionPoint(QRect* selectionPoint, const QPoint & p);
+ virtual bool setCoords(const QString & s);
+ virtual void setRect(const QRect & r);
+ virtual QString typeString() const { return i18n("Circle"); }
+ virtual QBitmap getMask() const;
+ virtual QString getHTMLCode() const;
+ virtual void updateSelectionPoints();
+
+};
+
+/**
+ * Represents a Rectangle Area
+ **/
+class PolyArea :public Area
+{
+ public:
+ PolyArea();
+ virtual ~PolyArea();
+
+ virtual Area* clone() const;
+ virtual bool contains(const QPoint & p) const;
+ virtual QString coordsToString() const;
+ virtual void draw(QPainter & p);
+ virtual void moveSelectionPoint(QRect* selectionPoint, const QPoint & p);
+ virtual void simplifyCoords();
+ virtual int addCoord(const QPoint & p);
+ virtual bool setCoords(const QString & s);
+ virtual QRect selectionRect() const;
+ virtual void setFinished(bool b);
+ virtual QString typeString() const { return i18n("Polygon"); }
+ virtual QBitmap getMask() const;
+ virtual QString getHTMLCode() const;
+ virtual void updateSelectionPoints();
+
+ private:
+ static int distance(const QPoint &p1, const QPoint &p2);
+ static bool isBetween(const QPoint &p, const QPoint &p1, const QPoint &p2);
+
+};
+
+/**
+ * Represents the default Area
+ **/
+class DefaultArea :public Area
+{
+ public:
+ DefaultArea();
+ virtual ~DefaultArea();
+
+ virtual Area* clone() const;
+ // the default area isn't drawn
+ virtual void draw(QPainter & p);
+ virtual QString typeString() const { return i18n("Default"); }
+ virtual QString getHTMLCode() const;
+
+};
+
+
+typedef QPtrList<Area> AreaList;
+typedef QPtrListIterator<Area> AreaListIterator;
+
+/**
+ * This class represents a selection of areas
+ * all operations performed on this class
+ * will be performed on the selected Areas
+ * the only actions that can be used is the
+ * move action
+ **/
+class AreaSelection : public Area {
+ public :
+ AreaSelection();
+ virtual ~AreaSelection();
+
+ /**
+ * New Methods
+ */
+
+ // Adding automatically selects the area
+ void add(Area *a);
+
+ // Removing automatically deselects the area
+ void remove(Area *a);
+
+ // Removes all areas from the list and deselects them
+ void reset();
+
+ uint count() const;
+
+ AreaList getAreaList() const;
+ AreaListIterator getAreaListIterator() const;
+ void setAreaList( const AreaList & areas );
+
+ bool isEmpty() const;
+
+ /**
+ * Overiden Methods of the Area class
+ */
+ virtual bool contains(const QPoint & p) const;
+
+ /**
+ *
+ **/
+ virtual QRect* onSelectionPoint(const QPoint & p, double zoom) const;
+
+ /**
+ * Only if one Area is selected the moveSelectionPoint method
+ * of that Area will be called
+ **/
+ virtual void moveSelectionPoint(QRect* selectionPoint, const QPoint & p);
+
+ virtual SelectionPointList* selectionPoints() const;
+
+ /**
+ * All Areas will be moved by dx and dy
+ **/
+ virtual void moveBy(int dx, int dy);
+
+ /**
+ * Calls for every selected Area the setArea with the
+ * corresponding Area in the copy Selection.
+ * IMPORTANT : works only if the copy Area is an AreaSelection
+ * and have the same number of Areas
+ **/
+ virtual void setArea(const Area & copy);
+ virtual void setAreaSelection(const AreaSelection & copy);
+
+ /**
+ * If only one Area is selected the setRect method of that Area
+ * will be called
+ **/
+ virtual void setRect(const QRect & r);
+ virtual QRect rect() const;
+
+
+ virtual QString typeString() const;
+ virtual ShapeType type() const;
+
+ // The selection is only a container
+ // so it is never drawn
+ virtual void draw(QPainter & p);
+
+
+ /**
+ * A deep copy of the Areas
+ **/
+ virtual Area* clone() const;
+
+ virtual void updateSelectionPoints();
+ virtual int addCoord(const QPoint & p);
+ virtual void insertCoord(int pos, const QPoint & p);
+ virtual void removeCoord(int pos);
+ virtual bool removeSelectionPoint(QRect * r);
+ virtual void moveCoord(int pos,const QPoint & p);
+ virtual QPointArray* coords() const;
+ virtual void highlightSelectionPoint(int);
+
+ virtual QRect selectionRect() const;
+
+ virtual QString attribute(const QString & name) const;
+ virtual void setAttribute(const QString & name, const QString & value);
+ virtual AttributeIterator firstAttribute() const;
+ virtual AttributeIterator lastAttribute() const;
+
+ virtual void setMoving(bool b);
+ virtual bool isMoving() const;
+
+
+ bool allAreasWithin(const QRect & r) const;
+
+ // makes the cache invalid
+ void invalidate();
+ private :
+
+ AreaList *_areas;
+
+ // The selectionRect and the rect are cached
+ // so even in const functions they must be changeable
+ mutable QRect _cachedSelectionRect;
+ mutable QRect _cachedRect;
+ mutable bool _selectionCacheValid;
+ mutable bool _rectCacheValid;
+
+};
+
+
+inline void AreaSelection::invalidate() {
+ _selectionCacheValid=false;
+ _rectCacheValid=false;
+}
+
+#endif
+
+
diff --git a/kimagemapeditor/kimecommands.cpp b/kimagemapeditor/kimecommands.cpp
new file mode 100644
index 00000000..e061a463
--- /dev/null
+++ b/kimagemapeditor/kimecommands.cpp
@@ -0,0 +1,384 @@
+/***************************************************************************
+ kimecommands.cpp - description
+ -------------------
+ begin : Fri May 25 2001
+ copyright : (C) 2001 by Jan Schäfer
+ email : j_schaef@informatik.uni-kl.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+#include <qstring.h>
+#include <kdebug.h>
+#include <klocale.h>
+
+#include "kimagemapeditor.h"
+#include "kimecommands.h"
+#include "drawzone.h"
+
+CutCommand::CutCommand(KImageMapEditor * document, const AreaSelection & a)
+ :
+
+#if KDE_VERSION < 300
+KCommand
+#else
+KNamedCommand
+#endif
+ (i18n( "Cut %1" ).arg( a.typeString() ))
+{
+ _document=document;
+ _cutAreaSelection=new AreaSelection();
+ _cutAreaSelection->setAreaList( a.getAreaList() );
+ _cutted=true;
+}
+
+
+CutCommand::~CutCommand()
+{
+ if (_cutted)
+ {
+ AreaList list = _cutAreaSelection->getAreaList();
+ for ( Area *a=list.first(); a != 0; a=list.next() ) {
+ delete a;
+ }
+ }
+
+ delete _cutAreaSelection;
+}
+
+void CutCommand::execute()
+{
+ // The Area won't be really delete
+ // it only gets removed from the AreaList
+ _document->deleteArea(_cutAreaSelection );
+ _document->updateActionAccess();
+ _cutted=true;
+}
+
+void CutCommand::unexecute()
+{
+ if (_document) {
+ _document->addArea( _cutAreaSelection );
+ _document->select( _cutAreaSelection );
+ _document->slotAreaChanged( _cutAreaSelection );
+ _cutted=false;
+ }
+}
+
+DeleteCommand::DeleteCommand(KImageMapEditor * document, const AreaSelection & a)
+ : CutCommand(document,a)
+{
+ setName(i18n( "Delete %1" ).arg( a.typeString() ));
+}
+
+PasteCommand::PasteCommand(KImageMapEditor *document, const AreaSelection & a)
+ :
+#if KDE_VERSION < 300
+KCommand
+#else
+KNamedCommand
+#endif
+ (i18n( "Paste %1" ).arg( a.typeString() ))
+{
+ _document=document;
+ _pasteAreaSelection=new AreaSelection();
+ _pasteAreaSelection->setAreaList( a.getAreaList() );
+ _pasted=true;
+ _wasUndoed=false;
+}
+
+PasteCommand::~PasteCommand ()
+{
+ if ( ! _pasted ) {
+ AreaList list=_pasteAreaSelection->getAreaList();
+ for (Area* a=list.first(); a != 0; a=list.next() ) {
+ delete a;
+ }
+ }
+
+ delete _pasteAreaSelection;
+}
+
+void PasteCommand::execute()
+{
+ _document->deselectAll();
+ _document->addArea( _pasteAreaSelection );
+ _document->select( _pasteAreaSelection );
+ _document->slotAreaChanged( _pasteAreaSelection );
+ _pasted=true;
+}
+
+void PasteCommand::unexecute()
+{
+ _document->deleteArea(_pasteAreaSelection );
+ _pasted=false;
+ _wasUndoed=true;
+}
+
+
+MoveCommand::MoveCommand (KImageMapEditor *document, AreaSelection * a, const QPoint & oldPoint)
+ :
+#if KDE_VERSION < 300
+KCommand
+#else
+KNamedCommand
+#endif
+(i18n( "Move %1" ).arg( a->typeString() ))
+{
+ _document=document;
+ _areaSelection=new AreaSelection();
+ _areaSelection->setAreaList( a->getAreaList() );
+ _oldPoint.setX(oldPoint.x());
+ _oldPoint.setY(oldPoint.y());
+
+ _newPoint.setX(a->rect().left());
+ _newPoint.setY(a->rect().top());
+}
+
+MoveCommand::~MoveCommand () {
+ delete _areaSelection;
+}
+
+void MoveCommand::execute()
+{
+ // only for repainting reasons
+ Area* tempArea = _areaSelection->clone();
+
+ _areaSelection->moveTo( _newPoint.x(), _newPoint.y() );
+
+ if (!_areaSelection->allAreasWithin(_document->getDrawZone()->getImageRect()))
+ _areaSelection->moveTo( _oldPoint.x(), _oldPoint.y() );
+
+ _document->selected()->invalidate();
+
+
+ _document->slotAreaChanged( tempArea );
+ _document->slotAreaChanged( _areaSelection );
+
+ delete tempArea;
+
+}
+
+void MoveCommand::unexecute()
+{
+ // only to erase the old Area
+ Area* tempArea = _areaSelection->clone();
+
+ _areaSelection->setMoving(true);
+ _areaSelection->moveTo( _oldPoint.x(), _oldPoint.y() );
+ _areaSelection->setMoving(false);
+
+ _document->selected()->invalidate();
+
+ _document->slotAreaChanged( tempArea );
+ _document->slotAreaChanged( _areaSelection );
+
+ delete tempArea;
+
+}
+
+
+ResizeCommand::ResizeCommand (KImageMapEditor *document, AreaSelection *a, Area *oldArea)
+ :
+#if KDE_VERSION < 300
+KCommand
+#else
+KNamedCommand
+#endif
+(i18n( "Resize %1" ).arg( a->typeString() ))
+{
+ _areaSelection=new AreaSelection();
+ _areaSelection->setAreaList( a->getAreaList() );
+
+ _newArea = a->clone();
+ _oldArea = oldArea->clone();
+ _document=document;
+}
+
+ResizeCommand::~ResizeCommand ()
+{
+ delete _newArea;
+ delete _oldArea;
+ delete _areaSelection;
+}
+
+void ResizeCommand::execute()
+{
+ _areaSelection->setArea ( *_newArea);
+ _areaSelection->setMoving(false);
+
+ _document->slotAreaChanged( _areaSelection );
+ _document->slotAreaChanged( _oldArea );
+
+
+}
+
+void ResizeCommand::unexecute()
+{
+ _areaSelection->setArea ( *_oldArea);
+ _areaSelection->setMoving(false);
+
+ _document->slotAreaChanged( _areaSelection );
+ _document->slotAreaChanged( _newArea );
+
+}
+
+
+
+AddPointCommand::AddPointCommand (KImageMapEditor *document, AreaSelection *a, const QPoint & p)
+ :
+#if KDE_VERSION < 300
+KCommand
+#else
+KNamedCommand
+#endif
+(i18n( "Add point to %1" ).arg( a->typeString() ))
+{
+ if (a->type()!=Area::Polygon)
+ {
+ kdDebug() << "trying to add a point to a " << a->typeString() << endl;
+ return;
+ }
+
+ _areaSelection=new AreaSelection();
+ _areaSelection->setAreaList( a->getAreaList() );
+
+ _point = p;
+ _document=document;
+}
+
+AddPointCommand::~AddPointCommand ()
+{
+ delete _areaSelection;
+}
+
+void AddPointCommand::execute()
+{
+ _coordpos = _areaSelection->addCoord(_point);
+ _areaSelection->setMoving(false);
+
+ _document->slotAreaChanged( _areaSelection );
+}
+
+void AddPointCommand::unexecute()
+{
+// QRect *selectionPoint = _areaSelection->onSelectionPoint(_point);
+ Area* repaintArea = _areaSelection->clone();
+
+ _areaSelection->removeCoord(_coordpos);
+ _areaSelection->setMoving(false);
+
+ _document->slotAreaChanged( _areaSelection );
+ _document->slotAreaChanged( repaintArea );
+
+ delete repaintArea;
+}
+
+RemovePointCommand::RemovePointCommand (KImageMapEditor *document, AreaSelection *a, Area *oldArea)
+ :
+#if KDE_VERSION < 300
+KCommand
+#else
+KNamedCommand
+#endif
+(i18n( "Remove point from %1" ).arg( a->typeString() ))
+{
+ if (a->type()!=Area::Polygon)
+ {
+ kdDebug() << "trying to remove a point to a " << a->typeString() << endl;
+ return;
+ }
+
+ _areaSelection=new AreaSelection();
+ _areaSelection->setAreaList( a->getAreaList() );
+
+ _newArea = a->clone();
+ _oldArea = oldArea->clone();
+ _document=document;
+}
+
+RemovePointCommand::~RemovePointCommand ()
+{
+ delete _newArea;
+ delete _oldArea;
+ delete _areaSelection;
+}
+
+void RemovePointCommand::execute()
+{
+ _areaSelection->setArea ( *_newArea);
+ _areaSelection->setMoving(false);
+
+ _document->slotAreaChanged( _areaSelection );
+ _document->slotAreaChanged( _oldArea );
+
+
+}
+
+void RemovePointCommand::unexecute()
+{
+ _areaSelection->setArea ( *_oldArea);
+ _areaSelection->setMoving(false);
+
+ _document->slotAreaChanged( _areaSelection );
+ _document->slotAreaChanged( _newArea );
+
+}
+
+
+
+CreateCommand::CreateCommand (KImageMapEditor *document, Area *area)
+ :
+#if KDE_VERSION < 300
+KCommand
+#else
+KNamedCommand
+#endif
+(i18n( "Create %1" ).arg( area->typeString() ))
+{
+ _document=document;
+ _area=area;
+ _created=true;
+ _wasUndoed=false;
+
+}
+
+CreateCommand::~CreateCommand ()
+{
+ if ( ! _created)
+ delete _area;
+}
+
+void CreateCommand::execute()
+{
+ if (_document) {
+
+ if ( _wasUndoed ) {
+ _document->addArea( _area );
+ _document->deselectAll();
+ _document->select( _area );
+ _document->slotAreaChanged( _area );
+ }
+ else
+ _document->addAreaAndEdit( _area );
+
+ _created=true;
+ }
+
+}
+
+void CreateCommand::unexecute()
+{
+ if (_document) {
+ _document->deleteArea( _area );
+ _created=false;
+ _wasUndoed=true;
+ }
+
+}
diff --git a/kimagemapeditor/kimecommands.h b/kimagemapeditor/kimecommands.h
new file mode 100644
index 00000000..946c09b4
--- /dev/null
+++ b/kimagemapeditor/kimecommands.h
@@ -0,0 +1,198 @@
+/***************************************************************************
+ kimecommands.h - description
+ -------------------
+ begin : Fri May 25 2001
+ copyright : (C) 2001 by Jan Schäfer
+ email : janschaefer@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef KIMECOMMANDS_H
+#define KIMECOMMANDS_H
+
+
+#include <kcommand.h>
+
+#include <kdeversion.h>
+
+class KImageMapEditor;
+class AreaSelection;
+
+
+
+class CutCommand : public
+
+#if KDE_VERSION < 300
+KCommand
+#else
+KNamedCommand
+#endif
+
+{
+ public:
+ CutCommand (KImageMapEditor * document, const AreaSelection & selection);
+ virtual ~CutCommand();
+
+ virtual void execute();
+ virtual void unexecute();
+
+ protected:
+ AreaSelection *_cutAreaSelection;
+ KImageMapEditor* _document;
+ bool _cutted;
+};
+
+/**
+ * Does the same like the cut command
+ * only have a different name in the Undo-History
+ **/
+class DeleteCommand : public CutCommand
+{
+ public :
+ DeleteCommand (KImageMapEditor * document, const AreaSelection & selection);
+};
+
+class PasteCommand : public
+#if KDE_VERSION < 300
+KCommand
+#else
+KNamedCommand
+#endif
+{
+ public:
+ PasteCommand (KImageMapEditor * document, const AreaSelection & selection);
+ ~PasteCommand ();
+
+ virtual void execute();
+ virtual void unexecute();
+
+ protected:
+ AreaSelection *_pasteAreaSelection;
+ KImageMapEditor* _document;
+ bool _pasted;
+ bool _wasUndoed;
+
+};
+
+class MoveCommand : public
+#if KDE_VERSION < 300
+KCommand
+#else
+KNamedCommand
+#endif
+{
+ public:
+ MoveCommand (KImageMapEditor *document, AreaSelection *a,const QPoint & oldPoint);
+ ~MoveCommand ();
+
+ virtual void execute();
+ virtual void unexecute();
+
+ protected:
+ QPoint _newPoint;
+ QPoint _oldPoint;
+
+ KImageMapEditor* _document;
+ AreaSelection *_areaSelection;
+//- Area *_oldArea;
+};
+
+class ResizeCommand : public
+#if KDE_VERSION < 300
+KCommand
+#else
+KNamedCommand
+#endif
+{
+ public:
+ ResizeCommand (KImageMapEditor *document, AreaSelection *a, Area *oldArea);
+ ~ResizeCommand ();
+
+ virtual void execute();
+ virtual void unexecute();
+
+ protected:
+
+ KImageMapEditor* _document;
+ AreaSelection *_areaSelection;
+ Area *_oldArea;
+ Area *_newArea;
+};
+
+class AddPointCommand : public
+#if KDE_VERSION < 300
+KCommand
+#else
+KNamedCommand
+#endif
+{
+ public:
+ AddPointCommand (KImageMapEditor *document, AreaSelection *a, const QPoint & p);
+ ~AddPointCommand ();
+
+ virtual void execute();
+ virtual void unexecute();
+
+ protected:
+
+ KImageMapEditor* _document;
+ AreaSelection *_areaSelection;
+ QPoint _point;
+ int _coordpos;
+};
+
+class RemovePointCommand : public
+#if KDE_VERSION < 300
+KCommand
+#else
+KNamedCommand
+#endif
+{
+ public:
+ RemovePointCommand (KImageMapEditor *document, AreaSelection *a, Area *oldArea);
+ ~RemovePointCommand ();
+
+ virtual void execute();
+ virtual void unexecute();
+
+ protected:
+
+ KImageMapEditor* _document;
+ AreaSelection *_areaSelection;
+ Area *_oldArea;
+ Area *_newArea;
+};
+
+
+class CreateCommand : public
+#if KDE_VERSION < 300
+KCommand
+#else
+KNamedCommand
+#endif
+{
+ public:
+ CreateCommand (KImageMapEditor *document, Area *area);
+ ~CreateCommand ();
+
+ virtual void execute();
+ virtual void unexecute();
+
+ protected:
+
+ KImageMapEditor* _document;
+ Area *_area;
+ bool _created;
+ bool _wasUndoed;
+};
+
+
+#endif
diff --git a/kimagemapeditor/kimecommon.h b/kimagemapeditor/kimecommon.h
new file mode 100644
index 00000000..4cc2d59f
--- /dev/null
+++ b/kimagemapeditor/kimecommon.h
@@ -0,0 +1,52 @@
+/***************************************************************************
+ kimecommon.h - description
+ -------------------
+ begin : Thu Apr 23 2002
+ copyright : (C) 2002 by Jan Schäfer
+ email : janschaefer@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+
+#ifndef __KIMECOMMON_H__
+#define __KIMECOMMON_H__
+
+inline int myabs(int i) {
+ if (i < 0)
+ return -i;
+ else
+ return i;
+}
+
+inline double myabs(double i) {
+ if (i < 0)
+ return -i;
+ else
+ return i;
+}
+
+inline int myround(double d) {
+ if ( (d-((int) d)) < 0.5 )
+ return (int) d;
+ else
+ return ((int) d)+1;
+}
+
+inline int roundUp(double d)
+{
+ if ( (d-((int) d)) == 0)
+ return (int) d;
+ else
+ return ((int) d)+1;
+}
+
+
+#endif
diff --git a/kimagemapeditor/kimedialogs.cpp b/kimagemapeditor/kimedialogs.cpp
new file mode 100644
index 00000000..27f104cb
--- /dev/null
+++ b/kimagemapeditor/kimedialogs.cpp
@@ -0,0 +1,874 @@
+/***************************************************************************
+ kimedialogs.cpp - description
+ -------------------
+ begin : Tue Apr 17 2001
+ copyright : (C) 2001 by Jan Sch�er
+ email : j_schaef@informatik.uni-kl.de
+***************************************************************************/
+
+/***************************************************************************
+* *
+* 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. *
+* *
+***************************************************************************/
+
+// QT
+//#include <qstring.h>
+#include <qcheckbox.h>
+#include <qmultilineedit.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qhbox.h>
+#include <qvbox.h>
+#include <qlineedit.h>
+#include <qlistbox.h>
+#include <qtable.h>
+#include <qgroupbox.h>
+#include <qspinbox.h>
+#include <qtabwidget.h>
+#include <qpointarray.h>
+#include <qimage.h>
+//#include <qwidget.h>
+// KDE
+#include <kiconloader.h>
+#include <kfiledialog.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <kapplication.h>
+#include <khtmlview.h>
+#include <khtml_part.h>
+#include <ktempfile.h>
+#include <kpushbutton.h>
+#include <kstdguiitem.h>
+
+// LOCAL
+#include "kimedialogs.h"
+
+CoordsEdit::CoordsEdit(QWidget *parent, Area* a)
+ : QWidget(parent)
+{
+ area=a;
+}
+
+void CoordsEdit::applyChanges() {
+ return;
+}
+
+void CoordsEdit::slotTriggerUpdate() {
+ applyChanges();
+ emit update();
+}
+
+CoordsEdit::~CoordsEdit()
+{
+}
+
+RectCoordsEdit::RectCoordsEdit(QWidget *parent, Area* a)
+ : CoordsEdit(parent,a)
+{
+ QGridLayout *layout= new QGridLayout(this,5,2,5,5);
+
+ topXSpin = new QSpinBox(this);
+ topXSpin->setMaxValue(INT_MAX);
+ topXSpin->setMinValue(0);
+ topXSpin->setValue(a->rect().left());
+ layout->addWidget(topXSpin,0,1);
+ connect( topXSpin, SIGNAL(valueChanged(const QString &)), this, SLOT(slotTriggerUpdate()));
+
+ QLabel *lbl= new QLabel(i18n("Top &X:"),this);
+ lbl->setBuddy(topXSpin);
+ layout->addWidget(lbl,0,0);
+
+ topYSpin = new QSpinBox(this);
+ topYSpin->setMaxValue(INT_MAX);
+ topYSpin->setMinValue(0);
+ topYSpin->setValue(a->rect().top());
+ layout->addWidget(topYSpin,1,1);
+ connect( topYSpin, SIGNAL(valueChanged(const QString &)), this, SLOT(slotTriggerUpdate()));
+
+ lbl= new QLabel(i18n("Top &Y:"),this);
+ lbl->setBuddy(topYSpin);
+ layout->addWidget(lbl,1,0);
+
+ widthSpin = new QSpinBox(this);
+ widthSpin->setMaxValue(INT_MAX);
+ widthSpin->setMinValue(0);
+ widthSpin->setValue(a->rect().width());
+ layout->addWidget(widthSpin,2,1);
+ connect( widthSpin, SIGNAL(valueChanged(const QString &)), this, SLOT(slotTriggerUpdate()));
+
+ lbl= new QLabel(i18n("&Width:"),this);
+ lbl->setBuddy(widthSpin);
+ layout->addWidget(lbl,2,0);
+
+ heightSpin = new QSpinBox(this);
+ heightSpin->setMaxValue(INT_MAX);
+ heightSpin->setMinValue(0);
+ heightSpin->setValue(a->rect().height());
+ layout->addWidget(heightSpin,3,1);
+ connect( heightSpin, SIGNAL(valueChanged(const QString &)), this, SLOT(slotTriggerUpdate()));
+
+ lbl= new QLabel(i18n("Hei&ght:"),this);
+ lbl->setBuddy(heightSpin);
+ layout->addWidget(lbl,3,0);
+
+ layout->setRowStretch(4,10);
+}
+
+void RectCoordsEdit::applyChanges() {
+ QRect r;
+ r.setLeft(topXSpin->text().toInt());
+ r.setTop(topYSpin->text().toInt());
+ r.setWidth(widthSpin->text().toInt());
+ r.setHeight(heightSpin->text().toInt());
+ area->setRect(r);
+}
+
+CircleCoordsEdit::CircleCoordsEdit(QWidget *parent, Area* a)
+ : CoordsEdit(parent,a)
+{
+ QGridLayout *layout= new QGridLayout(this,4,2,5,5);
+
+ centerXSpin = new QSpinBox(this);
+ centerXSpin->setMaxValue(INT_MAX);
+ centerXSpin->setMinValue(0);
+ centerXSpin->setValue(a->rect().center().x());
+ layout->addWidget(centerXSpin,0,1);
+ connect( centerXSpin, SIGNAL(valueChanged(const QString &)), this, SLOT(slotTriggerUpdate()));
+
+ QLabel *lbl= new QLabel(i18n("Center &X:"),this);
+ lbl->setBuddy(centerXSpin);
+ layout->addWidget(lbl,0,0);
+
+ centerYSpin = new QSpinBox(this);
+ centerYSpin->setMaxValue(INT_MAX);
+ centerYSpin->setMinValue(0);
+ centerYSpin->setValue(a->rect().center().y());
+ layout->addWidget(centerYSpin,1,1);
+ connect( centerYSpin, SIGNAL(valueChanged(const QString &)), this, SLOT(slotTriggerUpdate()));
+
+
+ lbl= new QLabel(i18n("Center &Y:"),this);
+ lbl->setBuddy(centerYSpin);
+ layout->addWidget(lbl,1,0);
+
+ radiusSpin = new QSpinBox(this);
+ radiusSpin->setMaxValue(INT_MAX);
+ radiusSpin->setMinValue(0);
+ radiusSpin->setValue(a->rect().width()/2);
+ layout->addWidget(radiusSpin,2,1);
+ connect( radiusSpin, SIGNAL(valueChanged(const QString &)), this, SLOT(slotTriggerUpdate()));
+
+
+ lbl= new QLabel(i18n("&Radius:"),this);
+ lbl->setBuddy(radiusSpin);
+ layout->addWidget(lbl,2,0);
+
+ layout->setRowStretch(3,10);
+
+}
+
+void CircleCoordsEdit::applyChanges() {
+ QRect r;
+ r.setWidth(radiusSpin->text().toInt()*2);
+ r.setHeight(radiusSpin->text().toInt()*2);
+ r.moveCenter(QPoint(centerXSpin->text().toInt(),
+ centerYSpin->text().toInt()));
+ area->setRect(r);
+}
+
+PolyCoordsEdit::PolyCoordsEdit(QWidget *parent, Area* a)
+ : CoordsEdit(parent,a)
+{
+ if (!a) return;
+ QVBoxLayout *layout= new QVBoxLayout(this);
+ int numPoints=a->coords()->count();
+ coordsTable= new QTable(numPoints,2,this);
+ coordsTable->horizontalHeader()->setLabel(0,"X");
+ coordsTable->horizontalHeader()->setLabel(1,"Y");
+ coordsTable->verticalHeader()->hide();
+ coordsTable->setLeftMargin(0);
+ coordsTable->setSelectionMode( QTable::Single );
+
+
+ for (int i=0;i<numPoints;i++) {
+ coordsTable->setText(i,0, QString::number(area->coords()->point(i).x()) );
+ coordsTable->setText(i,1, QString::number(area->coords()->point(i).y()) );
+ }
+
+ connect( coordsTable, SIGNAL(currentChanged(int,int)), this, SLOT(slotHighlightPoint(int)));
+
+// coordsTable->setMinimumHeight(50);
+// coordsTable->setMaximumHeight(400);
+// coordsTable->resizeContents(100,100);
+ coordsTable->resize(coordsTable->width(),100);
+ layout->addWidget(coordsTable);
+ layout->setStretchFactor(coordsTable,-1);
+ QHBox *hbox= new QHBox(this);
+ QPushButton *addBtn=new QPushButton(i18n("Add"),hbox);
+ connect( addBtn, SIGNAL(pressed()), this, SLOT(slotAddPoint()));
+ QPushButton *removeBtn=new QPushButton(i18n("Remove"),hbox);
+ connect( removeBtn, SIGNAL(pressed()), this, SLOT(slotRemovePoint()));
+
+ layout->addWidget(hbox);
+ slotHighlightPoint(1);
+}
+
+PolyCoordsEdit::~PolyCoordsEdit() {
+ if (area)
+ area->highlightSelectionPoint(-1);
+}
+
+void PolyCoordsEdit::slotHighlightPoint(int row) {
+ if (!area) return;
+ area->highlightSelectionPoint(row);
+ emit update();
+}
+
+
+void PolyCoordsEdit::slotAddPoint() {
+ int newPos= coordsTable->currentRow();
+ QPoint currentPoint=area->coords()->point(newPos);
+ area->insertCoord(newPos,currentPoint);
+
+ int count=area->coords()->size();
+
+ coordsTable->setNumRows(count);
+
+ for (int i=0;i<count;i++) {
+ coordsTable->setText(i,0, QString::number(area->coords()->point(i).x()) );
+ coordsTable->setText(i,1, QString::number(area->coords()->point(i).y()) );
+ }
+
+ emit update();
+}
+
+void PolyCoordsEdit::slotRemovePoint() {
+ int currentPos= coordsTable->currentRow();
+
+ area->removeCoord(currentPos);
+
+ int count=area->coords()->size();
+
+ coordsTable->setNumRows(count);
+
+ for (int i=0;i<count;i++) {
+ coordsTable->setText(i,0, QString::number(area->coords()->point(i).x()) );
+ coordsTable->setText(i,1, QString::number(area->coords()->point(i).y()) );
+ }
+
+ emit update();
+}
+
+void PolyCoordsEdit::applyChanges() {
+ int count=coordsTable->numRows();
+
+ for (int i=0;i<count;i++) {
+ QPoint newPoint( coordsTable->text(i,0).toInt(),
+ coordsTable->text(i,1).toInt());
+
+ area->moveCoord(i,newPoint);
+ }
+}
+
+SelectionCoordsEdit::SelectionCoordsEdit(QWidget *parent, Area* a)
+ : CoordsEdit(parent,a)
+{
+ QGridLayout *layout= new QGridLayout(this,2,2);
+
+ topXSpin = new QSpinBox(this);
+ topXSpin->setMaxValue(INT_MAX);
+ topXSpin->setMinValue(0);
+ topXSpin->setValue(a->rect().left());
+ layout->addWidget(topXSpin,0,1);
+ connect( topXSpin, SIGNAL(valueChanged(const QString &)), this, SLOT(slotTriggerUpdate()));
+
+ QLabel *lbl= new QLabel(i18n("Top &X"),this);
+ lbl->setBuddy(topXSpin);
+ layout->addWidget(lbl,0,0);
+
+ topYSpin = new QSpinBox(this);
+ topYSpin->setMaxValue(INT_MAX);
+ topYSpin->setMinValue(0);
+ topYSpin->setValue(a->rect().top());
+ layout->addWidget(topYSpin,1,1);
+ connect( topYSpin, SIGNAL(valueChanged(const QString &)), this, SLOT(slotTriggerUpdate()));
+
+ lbl= new QLabel(i18n("Top &Y"),this);
+ lbl->setBuddy(topYSpin);
+ layout->addWidget(lbl,1,0);
+}
+
+void SelectionCoordsEdit::applyChanges() {
+ area->moveTo(topXSpin->text().toInt(), topYSpin->text().toInt());
+}
+
+
+
+QLineEdit* AreaDialog::createLineEdit(QWidget* parent, QGridLayout *layout, int y, const QString & value, const QString & name)
+{
+ QLineEdit* edit=new QLineEdit(value,parent);
+ layout->addWidget(edit,y,2);
+ QLabel* lbl=new QLabel(name,parent);
+ lbl->setBuddy(edit);
+ layout->addWidget(lbl,y,1);
+
+ return edit;
+}
+
+QWidget* AreaDialog::createGeneralPage()
+{
+ QFrame* page = new QFrame(this);
+ QGridLayout* layout = new QGridLayout(page,5,2,5,5);
+
+
+ QHBox *hbox= new QHBox(page);
+ hrefEdit = new QLineEdit(area->attribute("href"),hbox);
+ QPushButton *btn = new QPushButton("",hbox);
+ btn->setPixmap(SmallIcon("fileopen"));
+ connect( btn, SIGNAL(pressed()), this, SLOT(slotChooseHref()));
+ hbox->setMinimumHeight(hbox->height());
+
+ layout->addWidget(hbox,0,2);
+ QLabel *lbl=new QLabel(i18n( "&HREF:" ),page);
+ lbl->setBuddy(hrefEdit);
+ layout->addWidget(lbl,0,1);
+
+ altEdit = createLineEdit(page,layout,1,area->attribute("alt"),i18n("Alt. &Text:"));
+ targetEdit = createLineEdit(page,layout,2,area->attribute("target"),i18n("Tar&get:"));
+ titleEdit = createLineEdit(page,layout,3,area->attribute("title"),i18n("Tit&le:"));
+
+ if (area->type()==Area::Default)
+ {
+ defaultAreaChk = new QCheckBox(i18n("Enable default map"),page);
+ if (area->finished())
+ defaultAreaChk->setChecked(true);
+ layout->addWidget(defaultAreaChk,3,2);
+ }
+
+
+ layout->setRowStretch(4,10);
+
+ return page;
+}
+
+QWidget* AreaDialog::createCoordsPage()
+{
+ QFrame* page = new QFrame(this);
+ QVBoxLayout *layout = new QVBoxLayout(page);
+ layout->setMargin(5);
+
+ coordsEdit = createCoordsEdit(page,area);
+ layout->addWidget(coordsEdit);
+ connect( coordsEdit, SIGNAL(update()), this, SLOT(slotUpdateArea()));
+
+ return page;
+}
+
+QWidget* AreaDialog::createJavascriptPage()
+{
+ QFrame* page = new QFrame(this);
+ QGridLayout* layout = new QGridLayout(page,8,2,5,5);
+
+ onClickEdit = createLineEdit(page,layout,0,area->attribute("onClick"),i18n("OnClick:"));
+ onDblClickEdit = createLineEdit(page,layout,1,area->attribute("onDblClick"),i18n("OnDblClick:"));
+ onMouseDownEdit = createLineEdit(page,layout,2,area->attribute("onMouseDown"),i18n("OnMouseDown:"));
+ onMouseUpEdit = createLineEdit(page,layout,3,area->attribute("onMouseUp"),i18n("OnMouseUp:"));
+ onMouseOverEdit = createLineEdit(page,layout,4,area->attribute("onMouseOver"),i18n("OnMouseOver:"));
+ onMouseMoveEdit = createLineEdit(page,layout,5,area->attribute("onMouseMove"),i18n("OnMouseMove:"));
+ onMouseOutEdit = createLineEdit(page,layout,6,area->attribute("onMouseOut"),i18n("OnMouseOut:"));
+
+ layout->setRowStretch(7,10);
+
+
+ return page;
+}
+
+QWidget* AreaDialog::createButtonBar()
+{
+ QHBox *box = new QHBox(this);
+ QWidget *spacer = new QWidget(box);
+ QPushButton *okBtn = new KPushButton(KStdGuiItem::ok(),box);
+ QPushButton *applyBtn = new KPushButton(KStdGuiItem::apply(),box);
+ QPushButton *cancelBtn = new KPushButton(KStdGuiItem::cancel(),box);
+
+ connect(okBtn, SIGNAL(clicked()), this, SLOT(slotOk()));
+ connect(applyBtn, SIGNAL(clicked()), this, SLOT(slotApply()));
+ connect(cancelBtn, SIGNAL(clicked()), this, SLOT(slotCancel()));
+
+ box->setSpacing(5);
+ box->setStretchFactor(spacer,10);
+
+ okBtn->setDefault(true);
+
+ return box;
+
+}
+
+AreaDialog::AreaDialog(KImageMapEditor* parent,Area * a)
+ : KDialog(parent->widget(),"",true)
+// : KDialogBase(Tabbed,i18n("Area Tag Editor"),Ok|Apply|Cancel,Ok,parent,"")
+// : KDialogBase(parent,"",true,"Area Tag Editor",Ok|Apply|Cancel,Ok,true)
+{
+ if (!a) {
+ slotCancel();
+ return;
+ }
+
+ _document=parent;
+
+ setCaption(i18n("Area Tag Editor"));
+
+ area=a;
+ QString shape="Default";
+ areaCopy= a->clone();
+ oldArea= new Area();
+ oldArea->setRect( a->rect() );
+
+ switch (a->type()) {
+ case Area::Rectangle : shape=i18n("Rectangle");break;
+ case Area::Circle : shape=i18n("Circle");break;
+ case Area::Polygon : shape=i18n("Polygon");break;
+ case Area::Selection : shape=i18n("Selection");break;
+ default : break;
+ }
+
+
+ // To get a margin around everything
+
+ QVBoxLayout *layout = new QVBoxLayout(this);
+
+ layout->setMargin(5);
+
+ QLabel *lbl = new QLabel("<b>"+shape+"</b>",this);
+ lbl->setTextFormat(Qt::RichText);
+ layout->addWidget(lbl);
+
+ QFrame *line = new QFrame(this);
+ line->setFrameStyle(QFrame::HLine | QFrame::Sunken);
+ line->setFixedHeight(10);
+ layout->addWidget(line);
+
+ QTabWidget *tab = new QTabWidget(this);
+
+ layout->addWidget(tab);
+
+ tab->addTab(createGeneralPage(),i18n("&General"));
+
+ if (a->type()==Area::Default)
+ {
+ shape=i18n("Default");
+ }
+ else
+ tab->addTab(createCoordsPage(),i18n("Coor&dinates"));
+
+ tab->addTab(createJavascriptPage(),i18n("&JavaScript"));
+
+ line = new QFrame(this);
+ line->setFrameStyle(QFrame::HLine | QFrame::Sunken);
+ line->setFixedHeight(10);
+ layout->addWidget(line);
+
+ layout->addWidget(createButtonBar());
+
+ setMinimumHeight(360);
+ setMinimumWidth(327);
+
+ resize(327,360);
+}
+
+AreaDialog::~AreaDialog() {
+ delete areaCopy;
+ delete oldArea;
+}
+
+CoordsEdit* AreaDialog::createCoordsEdit(QWidget *parent, Area *a) {
+ if (!a) return 0;
+ switch (a->type()) {
+ case Area::Rectangle :
+ return new RectCoordsEdit(parent,a);
+ break;
+ case Area::Circle :
+ return new CircleCoordsEdit(parent,a);
+ break;
+ case Area::Polygon :
+ return new PolyCoordsEdit(parent,a);
+ break;
+ case Area::Selection :
+ return new SelectionCoordsEdit(parent,a);
+ break;
+ case Area::Default : return new CoordsEdit(parent,a); break;
+ default : return new CoordsEdit(parent,a);break;
+ }
+}
+
+void AreaDialog::slotChooseHref() {
+ KURL url=KFileDialog::getOpenURL(QString::null, "*|" + i18n( "All Files" ), this, i18n("Choose File"));
+ if (!url.isEmpty()) {
+ hrefEdit->setText(url.url());
+ }
+}
+
+void AreaDialog::slotOk() {
+ if (area)
+ {
+ area->highlightSelectionPoint(-1);
+ if (area->type()==Area::Default)
+ area->setFinished(defaultAreaChk->isChecked());
+ }
+ slotApply();
+ accept();
+
+}
+
+void AreaDialog::slotApply() {
+ if (area) {
+ if (area->type()!=Area::Default)
+ coordsEdit->applyChanges();
+
+ area->setAttribute("href",hrefEdit->text());
+ area->setAttribute("alt",altEdit->text());
+ area->setAttribute("target",targetEdit->text());
+ area->setAttribute("title",titleEdit->text());
+ area->setAttribute("onclick",onClickEdit->text());
+ area->setAttribute("ondblclick",onDblClickEdit->text());
+ area->setAttribute("onmousedown",onMouseDownEdit->text());
+ area->setAttribute("onmouseup",onMouseUpEdit->text());
+ area->setAttribute("onmousemove",onMouseMoveEdit->text());
+ area->setAttribute("onmouseover",onMouseOverEdit->text());
+ area->setAttribute("onmouseout",onMouseOutEdit->text());
+
+ // redraw old area to get rid of it
+ emit areaChanged(oldArea);
+ // draw new area
+ emit areaChanged(area);
+ oldArea->setRect(area->rect());
+ }
+}
+
+void AreaDialog::slotCancel() {
+ if (area) {
+ AreaSelection *selection=0L;
+ if ( (selection=dynamic_cast<AreaSelection*>(areaCopy)) )
+ area->setArea(*selection);
+ else
+ area->setArea(*areaCopy);
+ area->highlightSelectionPoint(-1);
+ emit areaChanged(oldArea);
+ emit areaChanged(area);
+ }
+ reject();
+}
+
+void AreaDialog::slotUpdateArea() {
+ emit areaChanged(oldArea);
+ // draw new area
+ emit areaChanged(area);
+ oldArea->setRect(area->rect());
+}
+
+ImageMapChooseDialog::ImageMapChooseDialog(QWidget* parent,QPtrList<MapTag> *_maps,QPtrList<ImageTag> *_images,const KURL & _baseUrl)
+ : KDialogBase(parent,"",true,i18n( "Choose Map & Image to Edit" ),Ok,Ok,true)
+{
+ baseUrl=_baseUrl;
+ maps=_maps;
+ images=_images;
+ currentMap=0L;
+ QWidget *page=new QWidget(this);
+ setMainWidget(page);
+ setCaption(baseUrl.fileName());
+ QVBoxLayout *layout = new QVBoxLayout(page,5,5);
+
+ QLabel *lbl= new QLabel(i18n("Select an image and/or a map that you want to edit"),page);
+ lbl->setFont(QFont("Sans Serif",12, QFont::Bold));
+ layout->addWidget(lbl);
+ QFrame *line= new QFrame(page);
+ line->setFrameStyle(QFrame::HLine | QFrame::Sunken);
+ line->setFixedHeight(10);
+ layout->addWidget(line,0);
+
+ QGridLayout *gridLayout= new QGridLayout(layout,2,3,5);
+ gridLayout->setRowStretch(0,0);
+ gridLayout->setRowStretch(1,100);
+ lbl=new QLabel(i18n("&Maps"),page);
+ mapListBox= new QListBox(page);
+ lbl->setBuddy(mapListBox);
+ gridLayout->addWidget(lbl,0,0);
+ gridLayout->addWidget(mapListBox,1,0);
+
+ line= new QFrame(page);
+ line->setFrameStyle(QFrame::VLine | QFrame::Sunken);
+ line->setFixedWidth(10);
+// line->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding));
+ gridLayout->addWidget(line,1,1);
+
+ lbl=new QLabel(i18n("Image Preview"),page);
+ gridLayout->addWidget(lbl,0,2);
+
+ imagePreview= new QLabel(page);
+ imagePreview->setFixedSize(310,210);
+ imagePreview->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding));
+ imagePreview->setFrameStyle(QLabel::Panel | QLabel::Sunken);
+ imagePreview->setIndent(5);
+ imagePreview->setBackgroundColor(QColor("white"));
+// imagePreview->setLineWidth(2);
+// imagePreview->setScaledContents(true);
+// lbl= new QLabel(i18n("&Maps"),page);
+// lbl->setBuddy(mapListBox);
+ gridLayout->addWidget(imagePreview,1,2);
+// layout->addLayout(gridLayout,1);
+
+ line= new QFrame(page);
+ line->setFrameStyle(QFrame::HLine | QFrame::Sunken);
+ line->setFixedHeight(10);
+ layout->addWidget(line,0);
+
+
+ if (maps->isEmpty()) {
+ mapListBox->insertItem(i18n("No maps found"));
+ mapListBox->setEnabled(false);
+ }
+ else {
+ for (MapTag *tag = maps->first(); tag!=0L; tag=maps->next()) {
+ mapListBox->insertItem(tag->name);
+ }
+ connect (mapListBox, SIGNAL(highlighted(int)), this, SLOT(slotMapChanged(int)));
+ }
+
+ initImageListTable(page);
+
+ if (! maps->isEmpty()) {
+ mapListBox->setCurrentItem(0);
+ slotMapChanged(0);
+ }
+
+ resize(510,460);
+}
+
+void ImageMapChooseDialog::initImageListTable(QWidget* parent) {
+
+
+ if (images->isEmpty()) {
+ imageListTable= new QTable(1,1,parent);
+ imageListTable->setText(0,0,i18n("No images found"));
+ imageListTable->setEnabled(false);
+ imageListTable->horizontalHeader()->hide();
+ imageListTable->setTopMargin(0);
+ imageListTable->setColumnStretchable(0,true);
+ } else {
+ imageListTable= new QTable(images->count(),2,parent);
+ imageListTable->setColumnStretchable(0,true);
+ }
+
+ imageListTable->verticalHeader()->hide();
+ imageListTable->setLeftMargin(0);
+
+ QLabel *lbl= new QLabel(i18n("&Images"),parent);
+ lbl->setBuddy(imageListTable);
+
+ parent->layout()->add(lbl);
+ parent->layout()->add(imageListTable);
+
+ if (images->isEmpty())
+ return;
+
+ imageListTable->horizontalHeader()->setLabel(0,i18n("Path"));
+ imageListTable->horizontalHeader()->setLabel(1,"usemap");
+
+ imageListTable->setSelectionMode(QTable::SingleRow);
+ imageListTable->setFocusStyle(QTable::FollowStyle);
+ imageListTable->clearSelection(true);
+
+
+ int row=0;
+ for (ImageTag *tag = images->first(); tag!=0L; tag=images->next()) {
+ QString src="";
+ QString usemap="";
+ if (tag->find("src"))
+ src=*tag->find("src");
+ if (tag->find("usemap"))
+ usemap=*tag->find("usemap");
+
+ imageListTable->setText(row,0,src);
+ imageListTable->setText(row,1,usemap);
+ row++;
+ }
+ connect (imageListTable, SIGNAL(selectionChanged()), this, SLOT(slotImageChanged()));
+
+ imageListTable->selectRow(0);
+ slotImageChanged();
+
+
+}
+
+ImageMapChooseDialog::~ImageMapChooseDialog() {
+}
+
+void ImageMapChooseDialog::slotImageChanged()
+{
+ int i=imageListTable->currentRow();
+ QImage pix;
+ if (images->at(i)->find("src")) {
+ QString str=*images->at(i)->find("src");
+ // relative url
+ pixUrl=KURL(baseUrl,str);
+ pix=QImage(pixUrl.path());
+ double zoom1=1;
+ double zoom2=1;
+ if (pix.width()>300)
+ zoom1=(double) 300/pix.width();
+ if (pix.height()>200)
+ zoom2=(double) 200/pix.height();
+
+
+ zoom1= zoom1 < zoom2 ? zoom1 : zoom2;
+ pix=pix.smoothScale((int)(pix.width()*zoom1),int(pix.height()*zoom1));
+ }
+ QPixmap pix2;
+ pix2.convertFromImage(pix);
+ imagePreview->setPixmap(pix2);
+
+// imagePreview->repaint();
+}
+
+void ImageMapChooseDialog::selectImageWithUsemap(const QString & usemap) {
+ for (int i=0; i<imageListTable->numRows(); i++) {
+ if (imageListTable->text(i,1)==usemap) {
+ imageListTable->selectRow(i);
+ slotImageChanged();
+ return;
+ }
+ }
+}
+
+void ImageMapChooseDialog::slotMapChanged(int i) {
+ currentMap=maps->at(i);
+ selectImageWithUsemap(currentMap->name);
+}
+
+PreferencesDialog::PreferencesDialog(QWidget *parent, KConfig* conf)
+ : KDialogBase(parent,"",true,i18n("Preferences"),Ok|Apply|Cancel,Ok,true)
+{
+ config = conf;
+ QVBox *page=new QVBox(this);
+ page->setSpacing(6);
+ setMainWidget(page);
+
+ QHBox *hbox= new QHBox(page);
+
+ QLabel *lbl = new QLabel(i18n("&Maximum image preview height:")+" ",hbox);
+ rowHeightSpinBox = new QSpinBox(hbox);
+ lbl->setBuddy(rowHeightSpinBox);
+
+ config->setGroup("Appearance");
+ rowHeightSpinBox->setMaxValue(1000);
+ rowHeightSpinBox->setMinValue(15);
+ rowHeightSpinBox->setFixedWidth(60);
+ rowHeightSpinBox->setValue(config->readNumEntry("maximum-preview-height",50));
+
+ config->setGroup("General");
+
+ hbox= new QHBox(page);
+ lbl = new QLabel(i18n("&Undo limit:")+" ",hbox);
+ undoSpinBox = new QSpinBox(hbox);
+ undoSpinBox->setFixedWidth(60);
+ lbl->setBuddy(undoSpinBox);
+
+ undoSpinBox->setMaxValue(100);
+ undoSpinBox->setMinValue(1);
+ undoSpinBox->setValue(config->readNumEntry("undo-level",20));
+
+ hbox= new QHBox(page);
+ lbl = new QLabel(i18n("&Redo limit:")+" ",hbox);
+
+ redoSpinBox = new QSpinBox(hbox);
+ redoSpinBox->setFixedWidth(60);
+ redoSpinBox->setMaxValue(100);
+ redoSpinBox->setMinValue(1);
+ redoSpinBox->setValue(config->readNumEntry("redo-level",20));
+ lbl->setBuddy(redoSpinBox);
+
+ startWithCheck = new QCheckBox(i18n("&Start with last used document"),page);
+ startWithCheck->setChecked(config->readBoolEntry("start-with-last-used-document",true));
+
+/*
+ hbox= new QHBox(page);
+ (void)new QLabel(i18n("Highlight Areas")+" ",hbox);
+
+ colorizeAreaChk = new QCheckBox(hbox);
+ colorizeAreaChk->setFixedWidth(60);
+ colorizeAreaChk->setChecked(kapp->config()->readBoolEntry("highlightareas",true));
+
+ hbox= new QHBox(page);
+ (void)new QLabel(i18n("Show alternative text")+" ",hbox);
+
+ showAltChk = new QCheckBox(hbox);
+ showAltChk->setFixedWidth(60);
+ showAltChk->setChecked(kapp->config()->readBoolEntry("showalt",true));
+*/
+}
+
+PreferencesDialog::~PreferencesDialog() {
+}
+
+void PreferencesDialog::slotDefault( void ) {
+ rowHeightSpinBox->setValue(50);
+}
+
+void PreferencesDialog::slotOk( void ) {
+ slotApply();
+ accept();
+}
+
+void PreferencesDialog::slotApply( void ) {
+ config->setGroup("Appearance");
+ config->writeEntry("maximum-preview-height",rowHeightSpinBox->cleanText().toInt());
+
+ config->setGroup("General Options");
+ config->writeEntry("undo-level",undoSpinBox->cleanText().toInt());
+ config->writeEntry("redo-level",redoSpinBox->cleanText().toInt());
+ config->writeEntry("start-with-last-used-document", startWithCheck->isChecked());
+
+ config->sync();
+ emit applyClicked();
+}
+
+HTMLPreviewDialog::HTMLPreviewDialog(QWidget* parent, KURL url, const QString & htmlCode)
+ : KDialogBase(parent, "", true, i18n("Preview"), KDialogBase::Ok)
+{
+ tempFile = new KTempFile(url.directory(false), ".html");
+ tempFile->setAutoDelete(true);
+ (*tempFile->textStream()) << htmlCode;
+ kdDebug() << "HTMLPreviewDialog: TempFile : " << tempFile->name() << endl;
+ tempFile->close();
+
+ QVBox *page = makeVBoxMainWidget();
+
+ htmlPart = new KHTMLPart(page,"htmlpart");
+// htmlView = new KHTMLView(htmlPart, page);
+// htmlView->setVScrollBarMode(QScrollView::Auto);
+// htmlView->setHScrollBarMode(QScrollView::Auto);
+// dialog->resize(dialog->calculateSize(edit->maxLineWidth(),edit->numLines()*));
+// dialog->adjustSize();
+ QLabel* lbl = new QLabel(page,"urllabel");
+
+ connect( htmlPart, SIGNAL( onURL(const QString&)), lbl, SLOT( setText(const QString&)));
+}
+
+HTMLPreviewDialog::~HTMLPreviewDialog() {
+ delete tempFile;
+ delete htmlPart;
+}
+
+void HTMLPreviewDialog::show() {
+ KDialogBase::show();
+ htmlPart->openURL(KURL( tempFile->name() ));
+// htmlView->layout();
+// htmlView->repaint();
+ resize(800,600);
+}
+
+#include "kimedialogs.moc"
diff --git a/kimagemapeditor/kimedialogs.h b/kimagemapeditor/kimedialogs.h
new file mode 100644
index 00000000..c87f8dfe
--- /dev/null
+++ b/kimagemapeditor/kimedialogs.h
@@ -0,0 +1,207 @@
+/***************************************************************************
+ kimedialogs.h - description
+ -------------------
+ begin : Tue Apr 17 2001
+ copyright : (C) 2001 by Jan Schäfer
+ email : janschaefer@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef KIMEDIALOGS_H
+#define KIMEDIALOGS_H
+
+#include <kdialog.h>
+#include <kdialogbase.h>
+
+#include <kurl.h>
+#include "kimagemapeditor.h"
+
+#include "kdeversion.h"
+
+class QLineEdit;
+class QMultiLineEdit;
+class QSpinBox;
+
+
+class CoordsEdit : public QWidget {
+Q_OBJECT
+ public :
+ CoordsEdit(QWidget *parent, Area* a);
+ virtual ~CoordsEdit();
+ virtual void applyChanges();
+ protected:
+ Area *area; // The working area
+ protected slots:
+ void slotTriggerUpdate();
+ signals:
+ void update();
+};
+
+class RectCoordsEdit : public CoordsEdit {
+ public:
+ RectCoordsEdit(QWidget *parent, Area* a);
+ virtual void applyChanges();
+ private:
+ QSpinBox *topXSpin;
+ QSpinBox *topYSpin;
+ QSpinBox *widthSpin;
+ QSpinBox *heightSpin;
+};
+
+class CircleCoordsEdit : public CoordsEdit {
+ public:
+ CircleCoordsEdit(QWidget *parent, Area* a);
+ virtual void applyChanges();
+ private:
+ QSpinBox *centerXSpin;
+ QSpinBox *centerYSpin;
+ QSpinBox *radiusSpin;
+};
+
+class QTable;
+
+class PolyCoordsEdit : public CoordsEdit {
+Q_OBJECT
+ public:
+ PolyCoordsEdit(QWidget *parent, Area* a);
+ ~PolyCoordsEdit();
+ virtual void applyChanges();
+ private:
+ QTable *coordsTable;
+ protected slots:
+ void slotAddPoint();
+ void slotRemovePoint();
+ void slotHighlightPoint(int);
+
+};
+
+class SelectionCoordsEdit : public CoordsEdit {
+Q_OBJECT
+ public:
+ SelectionCoordsEdit(QWidget *parent, Area* a);
+ virtual void applyChanges();
+ private:
+ QSpinBox *topXSpin;
+ QSpinBox *topYSpin;
+
+};
+
+
+class QCheckBox;
+class QGridLayout;
+
+class AreaDialog : public KDialog {
+Q_OBJECT
+ private:
+ Area *area;
+ Area *oldArea; // Only for drawing reasons
+ Area *areaCopy; // A copy for restoring the original area if user press cancel
+ QLineEdit *hrefEdit;
+ QLineEdit *altEdit;
+ QLineEdit *targetEdit;
+ QLineEdit *titleEdit;
+
+ QLineEdit *onClickEdit;
+ QLineEdit *onDblClickEdit;
+ QLineEdit *onMouseDownEdit;
+ QLineEdit *onMouseUpEdit;
+ QLineEdit *onMouseOverEdit;
+ QLineEdit *onMouseMoveEdit;
+ QLineEdit *onMouseOutEdit;
+
+ CoordsEdit *coordsEdit;
+ CoordsEdit* createCoordsEdit(QWidget *parent, Area *a);
+ QCheckBox *defaultAreaChk;
+ KImageMapEditor *_document;
+
+
+ public:
+ AreaDialog(KImageMapEditor* parent,Area * a);
+ ~AreaDialog();
+ protected slots:
+ virtual void slotOk();
+ virtual void slotApply();
+ virtual void slotCancel();
+ void slotChooseHref();
+ void slotUpdateArea();
+
+ QLineEdit* createLineEdit(QWidget* parent, QGridLayout *layout, int y, const QString & value, const QString & name);
+ QWidget* createGeneralPage();
+ QWidget* createCoordsPage();
+ QWidget* createJavascriptPage();
+ QWidget* createButtonBar();
+ signals:
+ void areaChanged(Area* a);
+};
+
+class QLineEdit;
+class QListBox;
+class QLabel;
+
+
+class ImageMapChooseDialog : public KDialogBase {
+Q_OBJECT
+ private:
+ QTable *imageListTable;
+ QLabel *imagePreview;
+ QListBox *mapListBox;
+ QLineEdit *mapNameEdit;
+ QPtrList<MapTag> *maps;
+ QPtrList<ImageTag> *images;
+ KURL baseUrl;
+ void initImageListTable(QWidget*);
+ public:
+ ImageMapChooseDialog(QWidget* parent,QPtrList<MapTag> *_maps,QPtrList<ImageTag> *_images, const KURL & _baseUrl);
+ ~ImageMapChooseDialog();
+ KURL pixUrl;
+ MapTag* currentMap;
+ protected slots:
+ void slotImageChanged();
+ void slotMapChanged(int i);
+ void selectImageWithUsemap(const QString & usemap);
+
+};
+
+class KConfig;
+
+class PreferencesDialog : public KDialogBase {
+Q_OBJECT
+ public:
+ PreferencesDialog(QWidget *parent,KConfig*);
+ ~PreferencesDialog();
+ protected slots:
+ virtual void slotDefault( void );
+ virtual void slotOk( void );
+ virtual void slotApply( void );
+ private:
+ QSpinBox *rowHeightSpinBox;
+ QSpinBox *undoSpinBox;
+ QSpinBox *redoSpinBox;
+// QCheckBox *colorizeAreaChk;
+// QCheckBox *showAltChk;
+ QCheckBox *startWithCheck;
+ KConfig *config;
+};
+
+class KHTMLPart;
+class KTempFile;
+
+class HTMLPreviewDialog : public KDialogBase {
+ public:
+ HTMLPreviewDialog(QWidget *, KURL, const QString &);
+ ~HTMLPreviewDialog();
+ virtual void show();
+ private:
+ KHTMLPart* htmlPart;
+ KTempFile* tempFile;
+};
+
+#endif
diff --git a/kimagemapeditor/kimeshell.cpp b/kimagemapeditor/kimeshell.cpp
new file mode 100644
index 00000000..d919d2b7
--- /dev/null
+++ b/kimagemapeditor/kimeshell.cpp
@@ -0,0 +1,296 @@
+/***************************************************************************
+ kimepart.cpp - description
+ -------------------
+ begin : Mon Aug 5 2002
+ copyright : (C) 2002 by Jan Sch�er
+ email : janschaefer@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+
+#include <iostream>
+
+#include <kaction.h>
+#include <kiconloader.h>
+#include <kstandarddirs.h>
+#include <kfiledialog.h>
+#include <kmessagebox.h>
+#include <kkeydialog.h>
+#include <kedittoolbar.h>
+#include <kstatusbar.h>
+#include <kapplication.h>
+#include <kdebug.h>
+
+#include <qhbox.h>
+
+#include "drawzone.h"
+#include "kimagemapeditor.h" // the KPart
+#include "kimeshell.h"
+#include "kimeshell.moc"
+
+KimeShell::KimeShell(const char *name )
+ : KParts::DockMainWindow( 0L, name )
+{
+ setXMLFile("kimagemapeditorui.rc");
+
+
+ KDockWidget* mainDock;
+ mainDock = createDockWidget( "MainDockWidget", 0L, 0L, "main_dock_widget");
+ QWidget *w = new QHBox( mainDock );
+// QLayout* layout = new QGridLayout( mainDock );
+
+ mainDock->setWidget( w );
+ // allow others to dock to the 4 sides
+ mainDock->setDockSite(KDockWidget::DockCorner);
+ // forbit docking abilities of mainDock itself
+ mainDock->setEnableDocking(KDockWidget::DockNone);
+ setView( mainDock); // central widget in a KDE mainwindow
+ setMainDockWidget( mainDock); // master dockwidget
+ m_part = new KImageMapEditor( w, "kimagemapeditor", this, "kimagemapeditor");
+
+
+// setCentralWidget( part->widget() );
+
+ setupActions();
+
+ _stdout=false;
+
+// createGUI( part );
+ createShellGUI( true );
+ guiFactory()->addClient( m_part );
+ KParts::GUIActivateEvent ev( true );
+ QApplication::sendEvent( m_part, &ev );
+ //setCentralWidget(part->widget());
+
+ if (!initialGeometrySet())
+ resize( QSize(725, 525).expandedTo(minimumSizeHint()));
+
+ connect( m_part, SIGNAL(setStatusBarText(const QString &)),
+ this, SLOT(slotSetStatusBarText ( const QString & )));
+
+ connect( m_part, SIGNAL(setWindowCaption(const QString &)),
+ this, SLOT(setCaption( const QString &)));
+
+ setAutoSaveSettings( "General Options" );
+
+}
+
+KimeShell::~KimeShell()
+{
+// delete part;
+}
+
+bool KimeShell::queryClose()
+{
+ if (_stdout) {
+ std::cout << m_part->getHtmlCode() << std::endl;
+ }
+
+ return m_part->queryClose();
+}
+
+
+bool KimeShell::queryExit()
+{
+// writeConfig();
+ saveProperties(kapp->config());
+
+ return true;
+}
+
+
+void KimeShell::setupActions()
+{
+ (void)KStdAction::openNew(this, SLOT(fileNew()), actionCollection());
+
+ // File Quit
+ (void)KStdAction::quit(this, SLOT(close()),actionCollection());
+
+
+ (void)KStdAction::showToolbar(this, SLOT(optionsShowToolbar()), actionCollection());
+ (void)KStdAction::keyBindings(this, SLOT(optionsConfigureKeys()), actionCollection());
+ (void)KStdAction::configureToolbars(this, SLOT(optionsConfigureToolbars()), actionCollection());
+ (void)KStdAction::showStatusbar(this, SLOT(optionsShowStatusbar()), actionCollection());
+
+
+}
+
+void KimeShell::fileNew()
+{
+ // this slot is called whenever the File->New menu is selected,
+ // the New shortcut is pressed (usually CTRL+N) or the New toolbar
+ // button is clicked
+
+ // About this function, the style guide (
+ // http://developer.kde.org/documentation/standards/kde/style/basics/index.html )
+ // says that it should open a new window if the document is _not_
+ // in its initial state. This is what we do here..
+ if ( ! m_part->url().isEmpty() || m_part->isModified() )
+ {
+ KimeShell * newShell = new KimeShell();
+
+ newShell->show();
+ newShell->readConfig();
+ };
+}
+
+void KimeShell::openFile(const KURL & url)
+{
+ m_part->openFile(url);
+}
+
+void KimeShell::openLastFile()
+{
+ if (m_part->config()->readBoolEntry("start-with-last-used-document",true))
+ m_part->openLastURL(m_part->config());
+}
+
+void KimeShell::fileOpen()
+{
+ KURL url=KFileDialog::getOpenURL(QString::null,
+ "*.png *.jpg *.jpeg *.gif *.htm *.html|" + i18n( "Web Files" ) + "\n"
+ "*.png *.jpg *.jpeg *.gif *.bmp *.xbm *.xpm *.pnm *.mng|" + i18n( "Images" ) + "\n"
+ "*.htm *.html|" + i18n( "HTML Files" ) + "\n"
+ "*.png|" + i18n( "PNG Images" ) + "\n*.jpg *.jpeg|" + i18n( "JPEG Images" ) + "\n*.gif|" + i18n( "GIF Images" ) + "\n*|" + i18n( "All Files" )
+ ,this,i18n("Choose Picture to Open"));
+
+ if (!url.isEmpty()) {
+ // About this function, the style guide (
+ // http://developer.kde.org/documentation/standards/kde/style/basics/index.html )
+ // says that it should open a new window if the document is _not_
+ // in its initial state. This is what we do here..
+ if ( m_part->url().isEmpty() && ! m_part->isModified() )
+ {
+ // we open the file in this window...
+ m_part->openURL(url);
+ }
+ else
+ {
+ // we open the file in a new window...
+ KimeShell* newWin = new KimeShell;
+ newWin->openFile( url );
+ newWin->show();
+ }
+ }
+}
+
+
+
+void KimeShell::readConfig() {
+ KConfig *config;
+
+ config = kapp->config();
+
+ config->setGroup("General Options");
+ readConfig(config);
+
+}
+
+void KimeShell::readConfig(KConfig* config) {
+// applyMainWindowSettings(config);
+// restoreWindowSize(config);
+ readDockConfig(config);
+}
+
+void KimeShell::writeConfig() {
+ KConfig *config;
+
+ config = kapp->config();
+
+ config->setGroup("General Options");
+ writeConfig(config);
+}
+
+void KimeShell::writeConfig(KConfig* config) {
+ saveMainWindowSettings(config);
+ saveWindowSize(config);
+ writeDockConfig(config);
+ config->sync();
+
+}
+
+
+void KimeShell::saveProperties(KConfig *config)
+{
+ //writeConfig(config);
+ m_part->saveProperties(config);
+ writeConfig();
+
+}
+
+void KimeShell::readProperties(KConfig *config)
+{
+ readConfig();
+ m_part->readProperties(config);
+
+
+}
+
+
+void KimeShell::optionsConfigureKeys() {
+// KKeyDialog::configureKeys(actionCollection(), "testprog_shell.rc");
+
+ KKeyDialog dlg;
+ dlg.insert(actionCollection());
+ dlg.insert(m_part->actionCollection());
+ dlg.configure();
+}
+
+void KimeShell::optionsConfigureToolbars()
+{
+#if defined(KDE_MAKE_VERSION)
+# if KDE_VERSION >= KDE_MAKE_VERSION(3,1,0)
+ saveMainWindowSettings(KGlobal::config(), autoSaveGroup());
+# else
+ saveMainWindowSettings(KGlobal::config() );
+# endif
+#else
+ saveMainWindowSettings(KGlobal::config() );
+#endif
+
+ // use the standard toolbar editor
+ KEditToolbar dlg(factory());
+ connect(&dlg, SIGNAL(newToolbarConfig()),
+ this, SLOT(applyNewToolbarConfig()));
+ dlg.exec();
+}
+
+void KimeShell::applyNewToolbarConfig()
+{
+#if defined(KDE_MAKE_VERSION)
+# if KDE_VERSION >= KDE_MAKE_VERSION(3,1,0)
+ applyMainWindowSettings(KGlobal::config(), autoSaveGroup());
+# else
+ applyMainWindowSettings(KGlobal::config());
+# endif
+#else
+ applyMainWindowSettings(KGlobal::config());
+#endif
+}
+
+
+void KimeShell::optionsShowToolbar()
+{
+ if (toolBar()->isVisible())
+ toolBar()->hide();
+ else
+ toolBar()->show();
+}
+
+void KimeShell::optionsShowStatusbar()
+{
+ if (statusBar()->isVisible())
+ statusBar()->hide();
+ else
+ statusBar()->show();
+}
+
+
diff --git a/kimagemapeditor/kimeshell.h b/kimagemapeditor/kimeshell.h
new file mode 100644
index 00000000..28026524
--- /dev/null
+++ b/kimagemapeditor/kimeshell.h
@@ -0,0 +1,81 @@
+/***************************************************************************
+ kimeshell.h - description
+ -------------------
+ begin : Mon Aug 5 2002
+ copyright : (C) 2002 by Jan Schäfer
+ email : janschaefer@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef KIMESHELL_H
+#define KIMESHELL_H
+
+#include <kparts/dockmainwindow.h>
+
+class KImageMapEditor;
+
+class KimeShell : public KParts::DockMainWindow
+{
+ Q_OBJECT
+
+public:
+ KimeShell( const char *name=0 );
+ virtual ~KimeShell();
+
+ void setStdout(bool b);
+ void openFile(const KURL & url);
+
+ /**
+ * Opens the last open file, if the
+ * user has configured to open the last
+ * file. Otherwise does nothing
+ */
+ void openLastFile();
+ void readConfig();
+ void writeConfig();
+
+protected:
+ void setupActions();
+ void readConfig(KConfig*);
+ void writeConfig(KConfig*);
+
+// virtual bool queryClose();
+ virtual void readProperties(KConfig *config);
+ virtual void saveProperties(KConfig *config);
+
+ virtual bool queryClose();
+ virtual bool queryExit();
+
+
+private slots:
+ void fileNew();
+ void fileOpen();
+ void optionsShowToolbar();
+ void optionsShowStatusbar();
+ void optionsConfigureKeys();
+ void optionsConfigureToolbars();
+
+ void applyNewToolbarConfig();
+private:
+ KImageMapEditor *m_part;
+
+ bool _stdout; // write HTML-Code to stdout on exit ?
+
+
+
+};
+
+inline void KimeShell::setStdout(bool b) {
+ _stdout=b;
+}
+
+
+#endif
diff --git a/kimagemapeditor/main.cpp b/kimagemapeditor/main.cpp
new file mode 100644
index 00000000..626a6e44
--- /dev/null
+++ b/kimagemapeditor/main.cpp
@@ -0,0 +1,91 @@
+/***************************************************************************
+ main.cpp - description
+ -------------------
+ begin : Die Apr 10 19:46:49 CEST 2001
+ copyright : (C) 2001 by Jan Sch�er
+ email : j_schaef@informatik.uni-kl.de
+***************************************************************************/
+
+/***************************************************************************
+* *
+* 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. *
+* *
+***************************************************************************/
+
+#include <kcmdlineargs.h>
+#include <kaboutdata.h>
+#include <klocale.h>
+#include <kapplication.h>
+#include <dcopclient.h>
+
+#include "kimeshell.h"
+#include <config.h>
+
+static const char *description =
+ I18N_NOOP("An HTML imagemap editor");
+
+
+static KCmdLineOptions options[] =
+{
+ { "c", 0, 0 },
+ { "stdout", I18N_NOOP("Write HTML-Code to stdout on exit"), 0 },
+ { "+[File]", I18N_NOOP("File to open"), 0 },
+ { 0, 0, 0 }
+ // INSERT YOUR COMMANDLINE OPTIONS HERE
+};
+
+int main(int argc, char *argv[])
+{
+
+ KAboutData aboutData( "kimagemapeditor", I18N_NOOP("KImageMapEditor"),
+ VERSION, description, KAboutData::License_GPL,
+ "(C) 2001-2008 Jan Schaefer", 0, "http://www.nongnu.org/kimagemap/", "janschaefer@users.sourceforge.net");
+ aboutData.addAuthor("Jan Schaefer",0, "janschaefer@users.sourceforge.net");
+ aboutData.addCredit("Joerg Jaspert",I18N_NOOP("For helping me with the Makefiles, and creating the Debian package"));
+ aboutData.addCredit("Aaron Seigo and Michael",I18N_NOOP("For helping me fixing --enable-final mode"));
+ aboutData.addCredit("Antonio Crevillen",I18N_NOOP("For the Spanish translation"));
+ aboutData.addCredit("Fabrice Mous",I18N_NOOP("For the Dutch translation"));
+ aboutData.addCredit("Germain Chazot",I18N_NOOP("For the French translation"));
+ KCmdLineArgs::init( argc, argv, &aboutData );
+ KCmdLineArgs::addCmdLineOptions( options ); // Add our own options.
+
+ KApplication a;
+ a.dcopClient()->registerAs(a.name());
+
+
+
+ if (a.isRestored())
+ {
+ RESTORE(KimeShell);
+ }
+ else
+ {
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+ if ( args->count() == 0 )
+ {
+ KimeShell *kimeShell = new KimeShell();
+ kimeShell->setStdout(args->isSet("stdout"));
+ kimeShell->readConfig();
+ kimeShell->show();
+ kimeShell->openLastFile();
+ }
+ else
+ {
+ int i = 0;
+ for (; i < args->count(); i++ )
+ {
+ KimeShell *kimeShell = new KimeShell();
+ kimeShell->setStdout(args->isSet("stdout"));
+ kimeShell->readConfig();
+ kimeShell->show();
+ kimeShell->openFile(args->url(i));
+ }
+ }
+ args->clear();
+ }
+
+ return a.exec();
+}
diff --git a/kimagemapeditor/mapslistview.cpp b/kimagemapeditor/mapslistview.cpp
new file mode 100644
index 00000000..ec89ae4a
--- /dev/null
+++ b/kimagemapeditor/mapslistview.cpp
@@ -0,0 +1,174 @@
+/***************************************************************************
+ mapslistview.cpp - description
+ -------------------
+ begin : Weg Feb 26 2003
+ copyright : (C) 2003 by Jan SchÃ?fer
+ email : janschaefer@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+// KDE
+#include <klistview.h>
+#include <klocale.h>
+#include <kdebug.h>
+
+// locale
+#include "mapslistview.h"
+
+
+MapsListView::MapsListView(QWidget *parent, const char *name)
+: QVBox(parent, name) {
+ _listView = new KListView(this);
+ _listView->addColumn(i18n("Maps"));
+ _listView->setFullWidth(true);
+ _listView->setSelectionMode(QListView::Single);
+ _listView->setItemsRenameable(true);
+
+ connect( _listView, SIGNAL( selectionChanged(QListViewItem*)),
+ this, SLOT( slotSelectionChanged(QListViewItem*)));
+
+ connect( _listView, SIGNAL( itemRenamed(QListViewItem*)),
+ this, SLOT( slotItemRenamed(QListViewItem*)));
+}
+
+
+MapsListView::~MapsListView() {
+}
+
+void MapsListView::addMap(const QString & name = QString::null) {
+ new QListViewItem(_listView,name);
+ //kdDebug() << "MapsListView::addMap : Added map '" << name << "'" << endl;
+
+}
+
+void MapsListView::addMaps(QPtrList<MapTag> * maps) {
+
+ for (MapTag *tag = maps->first(); tag!=0L; tag=maps->next()) {
+ addMap(tag->name);
+ }
+}
+
+void MapsListView::selectMap(const QString & name) {
+ QListViewItem* item = _listView->findItem(name,0);
+ if (item) {
+ selectMap(item);
+ } else
+ kdWarning() << "MapsListView::selectMap : Couldn't found map '" << name << "'" << endl;
+
+}
+
+void MapsListView::selectMap(QListViewItem* item) {
+ if (item)
+ _listView->setSelected(item,true);
+}
+
+
+QString MapsListView::selectedMap() {
+ QString result;
+
+ QListViewItem* item = _listView->selectedItem();
+ if (item)
+ result = item->text(0);
+ else
+ kdWarning() << "MapsListView::selectedMap : No map selected !" << endl;
+
+ return result;
+}
+
+void MapsListView::removeMap(const QString & name) {
+ QListViewItem* item = _listView->findItem(name,0);
+ if (item) {
+ _listView->takeItem(item);
+ _listView->setSelected(_listView->currentItem(),true);
+// kdDebug() << "MapsListView::removeMap : Removed map '" << name << "'" << endl;
+ } else
+ kdWarning() << "MapsListView::removeMap : Couldn't found map '" << name << "'" << endl;
+}
+
+void MapsListView::clear() {
+ _listView->clear();
+}
+
+void MapsListView::slotSelectionChanged(QListViewItem* item) {
+ QString name = item->text(0);
+ emit mapSelected(name);
+}
+
+void MapsListView::slotItemRenamed(QListViewItem* item) {
+ QString name = item->text(0);
+ emit mapRenamed(name);
+}
+
+void MapsListView::changeMapName(const QString & oldName, const QString & newName) {
+// kdDebug() << "MapsListView::changeMapName : " << oldName << " to " << newName << endl;
+ QListViewItem* item = _listView->findItem(oldName,0);
+ if (item) {
+ item->setText(0,newName);
+// kdDebug() << "MapsListView::changeMapName : successful" << endl;
+ }
+ else {
+ kdWarning() << "MapsListView::changeMapName : Chouldn't find map with name '" << oldName << "'" << endl;
+ }
+
+}
+
+
+bool MapsListView::nameAlreadyExists(const QString & name) {
+// kdDebug() << "MapsListView::nameAlreadyExists : " << name << " ? " << endl;
+ bool result = false;
+ QListViewItem* item = 0L;
+ for(item = _listView->firstChild(); item; item = item->nextSibling()) {
+ QString otherMap = item->text(0);
+ if(name == otherMap) {
+ result = true;
+ break;
+ }
+ }
+
+// kdDebug() << "MapsListView::nameAlreadyExists : " << name << " : " << result << endl;
+
+ return result;
+}
+
+QStringList MapsListView::getMaps() {
+ QStringList result;
+
+ QListViewItem* item = 0L;
+ for(item = _listView->firstChild(); item; item = item->nextSibling()) {
+ QString map = item->text(0);
+ result << map;
+ }
+
+ return result;
+}
+
+QString MapsListView::getUnusedMapName() {
+ QString result;
+ QString attempt;
+ int i=0;
+ while(result.isEmpty()) {
+ i++;
+ attempt = i18n("unnamed");
+ attempt += QString::number(i);
+ if (nameAlreadyExists(attempt))
+ continue;
+
+ result = attempt;
+ }
+
+// kdDebug() << "MapsListView::getUnusedMapName : Found an unused name : '" << result << "'" << endl;
+ return result;
+}
+
+uint MapsListView::count() {
+ return _listView->childCount();
+}
+
+#include "mapslistview.moc"
diff --git a/kimagemapeditor/mapslistview.h b/kimagemapeditor/mapslistview.h
new file mode 100644
index 00000000..559725a2
--- /dev/null
+++ b/kimagemapeditor/mapslistview.h
@@ -0,0 +1,126 @@
+/***************************************************************************
+ mapslistview.h - description
+ -------------------
+ begin : Weg Feb 26 2003
+ copyright : (C) 2003 by Jan Schäfer
+ email : janschaefer@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef _MAPSLISTVIEW_H_
+#define _MAPSLISTVIEW_H_
+
+#include <qvbox.h>
+
+#include "kimagemapeditor.h"
+class KListView;
+
+/**
+ * Simple class that shows all map tags of the current open html file in a ListView
+ *
+ * Jan Schaefer
+ **/
+class MapsListView : public QVBox
+{
+Q_OBJECT
+public:
+ MapsListView(QWidget *parent, const char *name);
+ ~MapsListView();
+
+ /**
+ * Adds the given map to the ListView
+ */
+ void addMap(const QString &);
+
+ /**
+ * Adds all maps of the given QList to the ListView
+ */
+ void addMaps(QPtrList<MapTag> *);
+
+ /**
+ * Removes the given map from the ListView
+ */
+ void removeMap(const QString &);
+
+ /**
+ * Set the the given map selected in the ListView.
+ * it does not emit mapSelected afterwards.
+ */
+ void selectMap(const QString &);
+
+ /**
+ * Selects the given ListViewItem and deselects the current selected item
+ */
+ void selectMap(QListViewItem* item);
+
+ /**
+ * Changes the name of the map with the @p oldName to @p newName
+ */
+ void changeMapName(const QString & oldName, const QString & newName);
+
+ /**
+ * Returns the current selected map
+ */
+ QString selectedMap();
+
+
+ /**
+ * Removes all maps from the ListView
+ */
+ void clear();
+
+ /**
+ * Returns a name for a map which is not used yet.
+ * Returns for example Unnamed1
+ */
+ QString getUnusedMapName();
+
+ /**
+ * Wether or not the given map name already exists
+ */
+ bool nameAlreadyExists(const QString &);
+
+ /**
+ * Returns a QStringList of all maps
+ */
+ QStringList getMaps();
+
+ /**
+ * Returns the number of maps
+ */
+ uint count();
+
+ KListView* listView() { return _listView; }
+protected:
+ KListView* _listView;
+
+protected slots:
+ void slotSelectionChanged(QListViewItem*);
+ void slotItemRenamed(QListViewItem*);
+
+signals:
+
+ /**
+ * Gets emitted when the user selects a map in
+ * the ListView
+ */
+ void mapSelected(const QString &);
+
+
+ /**
+ * Emitted when the user has renamed a map in the ListView
+ */
+ void mapRenamed(const QString & newName);
+
+
+};
+
+#endif
diff --git a/kimagemapeditor/pics/Makefile.am b/kimagemapeditor/pics/Makefile.am
new file mode 100644
index 00000000..4d7ead61
--- /dev/null
+++ b/kimagemapeditor/pics/Makefile.am
@@ -0,0 +1,8 @@
+KDE_ICON = kimagemapeditor
+
+appicondir = $(kde_datadir)/kimagemapeditor/icons
+appicon_ICON = addpoint arrow circle circle2 freehand lower polygon raise rectangle removepoint
+
+picturesdir = $(kde_datadir)/kimagemapeditor
+pictures_DATA = addpointcursor.png freehandcursor.png polygoncursor.png removepointcursor.png
+
diff --git a/kimagemapeditor/pics/addpointcursor.png b/kimagemapeditor/pics/addpointcursor.png
new file mode 100644
index 00000000..0fe9f853
--- /dev/null
+++ b/kimagemapeditor/pics/addpointcursor.png
Binary files differ
diff --git a/kimagemapeditor/pics/freehandcursor.png b/kimagemapeditor/pics/freehandcursor.png
new file mode 100644
index 00000000..2f7f1163
--- /dev/null
+++ b/kimagemapeditor/pics/freehandcursor.png
Binary files differ
diff --git a/kimagemapeditor/pics/hi16-app-kimagemapeditor.png b/kimagemapeditor/pics/hi16-app-kimagemapeditor.png
new file mode 100644
index 00000000..cfdea0a0
--- /dev/null
+++ b/kimagemapeditor/pics/hi16-app-kimagemapeditor.png
Binary files differ
diff --git a/kimagemapeditor/pics/hi22-action-addpoint.png b/kimagemapeditor/pics/hi22-action-addpoint.png
new file mode 100644
index 00000000..51114fdf
--- /dev/null
+++ b/kimagemapeditor/pics/hi22-action-addpoint.png
Binary files differ
diff --git a/kimagemapeditor/pics/hi22-action-arrow.png b/kimagemapeditor/pics/hi22-action-arrow.png
new file mode 100644
index 00000000..dfbeabaa
--- /dev/null
+++ b/kimagemapeditor/pics/hi22-action-arrow.png
Binary files differ
diff --git a/kimagemapeditor/pics/hi22-action-circle.png b/kimagemapeditor/pics/hi22-action-circle.png
new file mode 100644
index 00000000..e0e616ce
--- /dev/null
+++ b/kimagemapeditor/pics/hi22-action-circle.png
Binary files differ
diff --git a/kimagemapeditor/pics/hi22-action-circle2.png b/kimagemapeditor/pics/hi22-action-circle2.png
new file mode 100644
index 00000000..45394d3b
--- /dev/null
+++ b/kimagemapeditor/pics/hi22-action-circle2.png
Binary files differ
diff --git a/kimagemapeditor/pics/hi22-action-freehand.png b/kimagemapeditor/pics/hi22-action-freehand.png
new file mode 100644
index 00000000..7ff9ce46
--- /dev/null
+++ b/kimagemapeditor/pics/hi22-action-freehand.png
Binary files differ
diff --git a/kimagemapeditor/pics/hi22-action-lower.png b/kimagemapeditor/pics/hi22-action-lower.png
new file mode 100644
index 00000000..18742bf0
--- /dev/null
+++ b/kimagemapeditor/pics/hi22-action-lower.png
Binary files differ
diff --git a/kimagemapeditor/pics/hi22-action-polygon.png b/kimagemapeditor/pics/hi22-action-polygon.png
new file mode 100644
index 00000000..66786d16
--- /dev/null
+++ b/kimagemapeditor/pics/hi22-action-polygon.png
Binary files differ
diff --git a/kimagemapeditor/pics/hi22-action-raise.png b/kimagemapeditor/pics/hi22-action-raise.png
new file mode 100644
index 00000000..3e2e1287
--- /dev/null
+++ b/kimagemapeditor/pics/hi22-action-raise.png
Binary files differ
diff --git a/kimagemapeditor/pics/hi22-action-rectangle.png b/kimagemapeditor/pics/hi22-action-rectangle.png
new file mode 100644
index 00000000..8ff0b2b7
--- /dev/null
+++ b/kimagemapeditor/pics/hi22-action-rectangle.png
Binary files differ
diff --git a/kimagemapeditor/pics/hi22-action-removepoint.png b/kimagemapeditor/pics/hi22-action-removepoint.png
new file mode 100644
index 00000000..065912bf
--- /dev/null
+++ b/kimagemapeditor/pics/hi22-action-removepoint.png
Binary files differ
diff --git a/kimagemapeditor/pics/hi32-app-kimagemapeditor.png b/kimagemapeditor/pics/hi32-app-kimagemapeditor.png
new file mode 100644
index 00000000..cb7558c2
--- /dev/null
+++ b/kimagemapeditor/pics/hi32-app-kimagemapeditor.png
Binary files differ
diff --git a/kimagemapeditor/pics/hi48-app-kimagemapeditor.png b/kimagemapeditor/pics/hi48-app-kimagemapeditor.png
new file mode 100644
index 00000000..c95bd08c
--- /dev/null
+++ b/kimagemapeditor/pics/hi48-app-kimagemapeditor.png
Binary files differ
diff --git a/kimagemapeditor/pics/lo16-app-kimagemapeditor.png b/kimagemapeditor/pics/lo16-app-kimagemapeditor.png
new file mode 100644
index 00000000..0985586b
--- /dev/null
+++ b/kimagemapeditor/pics/lo16-app-kimagemapeditor.png
Binary files differ
diff --git a/kimagemapeditor/pics/lo32-app-kimagemapeditor.png b/kimagemapeditor/pics/lo32-app-kimagemapeditor.png
new file mode 100644
index 00000000..12542c8a
--- /dev/null
+++ b/kimagemapeditor/pics/lo32-app-kimagemapeditor.png
Binary files differ
diff --git a/kimagemapeditor/pics/polygoncursor.png b/kimagemapeditor/pics/polygoncursor.png
new file mode 100644
index 00000000..e315aa51
--- /dev/null
+++ b/kimagemapeditor/pics/polygoncursor.png
Binary files differ
diff --git a/kimagemapeditor/pics/removepointcursor.png b/kimagemapeditor/pics/removepointcursor.png
new file mode 100644
index 00000000..91187d1d
--- /dev/null
+++ b/kimagemapeditor/pics/removepointcursor.png
Binary files differ
diff --git a/kimagemapeditor/qextfileinfo.cpp b/kimagemapeditor/qextfileinfo.cpp
new file mode 100644
index 00000000..c52c48b5
--- /dev/null
+++ b/kimagemapeditor/qextfileinfo.cpp
@@ -0,0 +1,347 @@
+/*
+ From WebMaker - KDE HTML Editor
+ Copyright (C) 1998, 1999 Alexei Dets <dets@services.ru>
+
+ Rewritten for Quanta Plus: (C) 2002 Andras Mantia <amantia@freemail.hu>
+
+ 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.
+*/
+
+
+//qt includes
+#include <qdir.h>
+#include <qapplication.h>
+#include <qptrlist.h>
+#include <qstringlist.h>
+#include <qregexp.h>
+#include <qtimer.h>
+
+//kde includes
+#include <kurl.h>
+#include <kio/job.h>
+#include <kio/netaccess.h>
+#include <kio/scheduler.h>
+#include <kdirlister.h>
+#include <kfileitem.h>
+#include <kglobal.h>
+#include <kdebug.h>
+
+//app includes
+#include "qextfileinfo.h"
+
+QString QExtFileInfo::lastErrorMsg = "";
+
+/** create a relative short url based in baseURL*/
+KURL QExtFileInfo::toRelative(const KURL& urlToConvert,const KURL& baseURL)
+{
+ KURL resultURL = urlToConvert;
+ if (urlToConvert.protocol() == baseURL.protocol())
+ {
+ QString path = urlToConvert.path();
+ QString basePath = baseURL.path(1);
+ if (path.startsWith("/"))
+ {
+ path.remove(0, 1);
+ basePath.remove(0, 1);
+ if ( basePath.right(1) != "/" ) basePath.append("/");
+
+ int pos=0;
+ int pos1=0;
+ for (;;)
+ {
+ pos=path.find("/");
+ pos1=basePath.find("/");
+ if ( pos<0 || pos1<0 ) break;
+ if ( path.left(pos+1 ) == basePath.left(pos1+1) )
+ {
+ path.remove(0, pos+1);
+ basePath.remove(0, pos1+1);
+ }
+ else
+ break;
+ };
+
+ if ( basePath == "/" ) basePath="";
+ int level = basePath.contains("/");
+ for (int i=0; i<level; i++)
+ {
+ path="../"+path;
+ };
+ }
+
+ resultURL.setPath(QDir::cleanDirPath(path));
+ }
+
+ if (urlToConvert.path().endsWith("/")) resultURL.adjustPath(1);
+ return resultURL;
+}
+/** convert relative filename to absolute */
+KURL QExtFileInfo::toAbsolute(const KURL& urlToConvert,const KURL& baseURL)
+{
+ KURL resultURL = urlToConvert;
+ if (urlToConvert.protocol() == baseURL.protocol() && !urlToConvert.path().startsWith("/"))
+ {
+ int pos;
+ QString cutname = urlToConvert.path();
+ QString cutdir = baseURL.path(1);
+ while ( (pos = cutname.find("../")) >=0 )
+ {
+ cutname.remove( 0, pos+3 );
+ cutdir.remove( cutdir.length()-1, 1 );
+ cutdir.remove( cutdir.findRev('/')+1 , 1000);
+ }
+ resultURL.setPath(QDir::cleanDirPath(cutdir+cutname));
+ }
+
+ if (urlToConvert.path().endsWith("/")) resultURL.adjustPath(1);
+ return resultURL;
+}
+
+/** All files in a dir.
+ The return will also contain the name of the subdirectories.
+ This is needed for empty directory adding/handling. (Andras)
+ Currently works only for local directories
+*/
+KURL::List QExtFileInfo::allFiles( const KURL& path, const QString& mask)
+{
+ QExtFileInfo internalFileInfo;
+ return internalFileInfo.allFilesInternal(path, mask);
+}
+
+KURL::List QExtFileInfo::allFilesRelative( const KURL& path, const QString& mask)
+{
+ QExtFileInfo internalFileInfo;
+ KURL::List r = internalFileInfo.allFilesInternal( path, mask);
+
+ KURL::List::Iterator it;
+ for ( it = r.begin(); it != r.end(); ++it )
+ {
+ *it = QExtFileInfo::toRelative( *it, path );
+ }
+
+ return r;
+}
+
+bool QExtFileInfo::createDir( const KURL& path )
+{
+ int i=0;
+ bool result;
+ KURL dir1, dir2 = KURL();
+ while ( !exists(path) && dir2.path() != path.path() )
+ {
+ dir1 = path;
+ dir2 = path;
+
+ dir1=cdUp(dir1);
+ while ( !exists(dir1) && dir1.path() != "/" )
+ {
+ dir1=cdUp(dir1);
+ dir2=cdUp(dir2);
+ // debug(d1);
+ }
+ // dir2.setPath(dir2.path(-1));
+ result = KIO::NetAccess::mkdir(dir2, 0L, -1);
+ i++;
+ }
+ result = exists(path);
+ return result;
+}
+
+KURL QExtFileInfo::cdUp(const KURL &url)
+{
+ KURL u = url;
+ QString dir = u.path(-1);
+ while ( !dir.isEmpty() && dir.right(1) != "/" )
+ {
+ dir.remove( dir.length()-1,1);
+ }
+ u.setPath(dir);
+ return u;
+}
+
+QString QExtFileInfo::shortName(const QString &fname)
+{
+ return fname.section("/",-1);
+}
+
+KURL QExtFileInfo::path( const KURL &url )
+{
+ return KURL( url.directory(false,false) );
+}
+
+KURL QExtFileInfo::home()
+{
+ KURL url;
+ url.setPath(QDir::currentDirPath()+"/");
+ return url;
+}
+
+
+bool QExtFileInfo::exists(const KURL& a_url)
+{
+// Andras: Don't use it now, as it brings up an extra dialog and need manual
+// intervention when usign fish
+// return KIO::NetAccess::exists(a_url, false);
+
+// No dialog when stating.
+ if ( a_url.isLocalFile() )
+ {
+ return QFile::exists( a_url.path() );
+ } else
+ {
+ QExtFileInfo internalFileInfo;
+ return internalFileInfo.internalExists(a_url);
+ }
+}
+
+/* Synchronouse copy, like NetAccess::file_copy in KDE 3.2 */
+bool QExtFileInfo::copy( const KURL& src, const KURL& target, int permissions,
+ bool overwrite, bool resume, QWidget* window )
+{
+ QExtFileInfo internalFileInfo;
+ return internalFileInfo.internalCopy( src, target, permissions, overwrite, resume, window );
+}
+
+/** No descriptions */
+KURL::List QExtFileInfo::allFilesInternal(const KURL& startURL, const QString& mask)
+{
+ dirListItems.clear();
+ if (internalExists(startURL))
+ {
+ lstFilters.setAutoDelete(true);
+ lstFilters.clear();
+ // Split on white space
+ QStringList list = QStringList::split( ' ', mask );
+ for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it )
+ lstFilters.append( new QRegExp(*it, false, true ) );
+
+ bJobOK = true;
+ KIO::ListJob *job = KIO::listRecursive(startURL, false, true);
+ connect(job, SIGNAL(entries(KIO::Job *, const KIO::UDSEntryList&)),
+ this, SLOT(slotNewEntries(KIO::Job *, const KIO::UDSEntryList&)));
+ connect( job, SIGNAL( result (KIO::Job *) ),
+ this, SLOT( slotResult (KIO::Job *) ) );
+
+ // kdDebug(24000) << "Now listing: " << startURL.url() << endl;
+ enter_loop();
+ lstFilters.clear();
+ if (!bJobOK)
+ {
+ // kdDebug(24000) << "Error while listing "<< startURL.url() << endl;
+ dirListItems.clear();
+ }
+ }
+ return dirListItems;
+}
+
+
+//Some hackery from KIO::NetAccess as they do not do exactly what we want
+/* return true if the url exists*/
+bool QExtFileInfo::internalExists(const KURL& url)
+{
+ bJobOK = true;
+ // kdDebug(24000)<<"QExtFileInfo::internalExists"<<endl;
+ KIO::StatJob * job = KIO::stat( url, false);
+ job->setDetails(0);
+ job->setSide(false); //check the url for writing
+ connect( job, SIGNAL( result (KIO::Job *) ),
+ this, SLOT( slotResult (KIO::Job *) ) );
+
+ //To avoid lock-ups, start a timer.
+ QTimer::singleShot(10*1000, this,SLOT(slotTimeout()));
+// kdDebug(24000)<<"QExtFileInfo::internalExists:before enter_loop"<<endl;
+ enter_loop();
+// kdDebug(24000)<<"QExtFileInfo::internalExists:after enter_loop"<<endl;
+ return bJobOK;
+}
+
+bool QExtFileInfo::internalCopy(const KURL& src, const KURL& target, int permissions,
+ bool overwrite, bool resume, QWidget* window)
+{
+ bJobOK = true; // success unless further error occurs
+
+ KIO::Scheduler::checkSlaveOnHold(true);
+ KIO::Job * job = KIO::file_copy( src, target, permissions, overwrite, resume );
+ job->setWindow (window);
+ connect( job, SIGNAL( result (KIO::Job *) ),
+ this, SLOT( slotResult (KIO::Job *) ) );
+
+ enter_loop();
+ return bJobOK;
+}
+
+
+void qt_enter_modal( QWidget *widget );
+void qt_leave_modal( QWidget *widget );
+
+void QExtFileInfo::enter_loop()
+{
+ QWidget dummy(0,0,WType_Dialog | WShowModal);
+ dummy.setFocusPolicy( QWidget::NoFocus );
+ qt_enter_modal(&dummy);
+// kdDebug(24000)<<"QExtFileInfo::enter_loop:before qApp->enter_loop()"<<endl;
+ qApp->enter_loop();
+// kdDebug(24000)<<"QExtFileInfo::enter_loop:after qApp->enter_loop()"<<endl;
+ qt_leave_modal(&dummy);
+}
+
+void QExtFileInfo::slotResult( KIO::Job * job )
+{
+ bJobOK = !job->error();
+ if ( !bJobOK )
+ {
+ if ( !lastErrorMsg )
+ lastErrorMsg = job->errorString();
+ }
+ if ( job->isA("KIO::StatJob") )
+ m_entry = static_cast<KIO::StatJob *>(job)->statResult();
+ qApp->exit_loop();
+}
+
+void QExtFileInfo::slotNewEntries(KIO::Job *job, const KIO::UDSEntryList& udsList)
+{
+ KURL url = static_cast<KIO::ListJob *>(job)->url();
+ url.adjustPath(-1);
+ // avoid creating these QStrings again and again
+ static const QString& dot = KGlobal::staticQString(".");
+ static const QString& dotdot = KGlobal::staticQString("..");
+
+ KIO::UDSEntryListConstIterator it = udsList.begin();
+ KIO::UDSEntryListConstIterator end = udsList.end();
+ KURL itemURL;
+ for ( ; it != end; ++it )
+ {
+ QString name;
+
+ // find out about the name
+ KIO::UDSEntry::ConstIterator entit = (*it).begin();
+ for( ; entit != (*it).end(); ++entit )
+ if ( (*entit).m_uds == KIO::UDS_NAME )
+ {
+ name = (*entit).m_str;
+ break;
+ }
+
+ if ( ! name.isEmpty() && name != dot && name != dotdot)
+ {
+ KFileItem* item = new KFileItem( *it, url, false, true );
+ itemURL = item->url();
+ if (item->isDir()) itemURL.adjustPath(1);
+ for ( QPtrListIterator<QRegExp> filterIt( lstFilters ); filterIt.current(); ++filterIt )
+ if ( filterIt.current()->exactMatch( item->text() ) )
+ dirListItems.append(itemURL);
+ delete item;
+ }
+ }
+}
+
+/** Timeout occured while waiting for some network function to return. */
+void QExtFileInfo::slotTimeout()
+{
+ bJobOK = false;
+ qApp->exit_loop();
+}
+#include "qextfileinfo.moc"
diff --git a/kimagemapeditor/qextfileinfo.h b/kimagemapeditor/qextfileinfo.h
new file mode 100644
index 00000000..20294bde
--- /dev/null
+++ b/kimagemapeditor/qextfileinfo.h
@@ -0,0 +1,75 @@
+/*
+ From WebMaker - KDE HTML Editor
+ Copyright (C) 1998, 1999 Alexei Dets <dets@services.ru>
+ Rewritten for Quanta Plus: (C) 2002 Andras Mantia <amantia@freemail.hu>
+
+ 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.
+*/
+
+#ifndef _QEXTFILEINFO_H_
+#define _QEXTFILEINFO_H_
+
+#include <kio/global.h>
+#include <kio/job.h>
+#include <kurl.h>
+#include <kfileitem.h>
+
+#include <qobject.h>
+#include <qptrlist.h>
+#include <qregexp.h>
+
+class QExtFileInfo:public QObject
+{
+ Q_OBJECT
+public:
+ QExtFileInfo() {};
+ ~QExtFileInfo() {};
+
+ /** create to ralative short name */
+ static KURL toRelative(const KURL& urlToConvert,const KURL& baseURL);
+ /** convert relative filename to absolute */
+ static KURL toAbsolute(const KURL& urlToConvert,const KURL& baseURL);
+ /** recurse function for all files in dir */
+ static KURL::List allFiles( const KURL& path, const QString &mask);
+ static KURL::List allFilesRelative( const KURL& path, const QString &mask);
+ /** create dir if don't exists */
+ static bool createDir(const KURL & path );
+ static KURL cdUp(const KURL &dir);
+ static QString shortName(const QString &fname );
+ static KURL path(const KURL &);
+ static KURL home();
+ static bool exists(const KURL& url);
+ static bool copy( const KURL& src, const KURL& dest, int permissions=-1,
+ bool overwrite=false, bool resume=false, QWidget* window = 0L );
+
+ void enter_loop();
+
+private:
+ bool internalExists(const KURL& url);
+ bool internalCopy(const KURL& src, const KURL& target, int permissions,
+ bool overwrite, bool resume, QWidget* window);
+
+ bool bJobOK;
+ static QString lastErrorMsg;
+ KIO::UDSEntry m_entry;
+ KURL::List dirListItems;
+ QPtrList<QRegExp> lstFilters;
+
+ /** No descriptions */
+ KURL::List allFilesInternal(const KURL& startURL, const QString& mask);
+
+// friend class I_like_this_class;
+
+private slots:
+ void slotResult( KIO::Job * job );
+ void slotNewEntries(KIO::Job *job, const KIO::UDSEntryList& udsList);
+public slots: // Public slots
+ /** Timeout occured while waiting for some network function to return. */
+ void slotTimeout();
+};
+
+
+#endif