summaryrefslogtreecommitdiffstats
path: root/kimagemapeditor/kimagemapeditor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kimagemapeditor/kimagemapeditor.cpp')
-rw-r--r--kimagemapeditor/kimagemapeditor.cpp2819
1 files changed, 2819 insertions, 0 deletions
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() );
+ }
+}