summaryrefslogtreecommitdiffstats
path: root/kig/kig
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commitce599e4f9f94b4eb00c1b5edb85bce5431ab3df2 (patch)
treed3bb9f5d25a2dc09ca81adecf39621d871534297 /kig/kig
downloadtdeedu-ce599e4f9f94b4eb00c1b5edb85bce5431ab3df2.tar.gz
tdeedu-ce599e4f9f94b4eb00c1b5edb85bce5431ab3df2.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdeedu@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kig/kig')
-rw-r--r--kig/kig/Makefile.am53
-rw-r--r--kig/kig/aboutdata.h89
-rw-r--r--kig/kig/hi128-app-kig.pngbin0 -> 11501 bytes
-rw-r--r--kig/kig/hi16-app-kig.pngbin0 -> 777 bytes
-rw-r--r--kig/kig/hi22-app-kig.pngbin0 -> 1210 bytes
-rw-r--r--kig/kig/hi32-app-kig.pngbin0 -> 1848 bytes
-rw-r--r--kig/kig/hi48-app-kig.pngbin0 -> 3042 bytes
-rw-r--r--kig/kig/hi64-app-kig.pngbin0 -> 4472 bytes
-rw-r--r--kig/kig/hisc-app-kig.svgzbin0 -> 3640 bytes
-rw-r--r--kig/kig/kig.cpp308
-rw-r--r--kig/kig/kig.desktop121
-rw-r--r--kig/kig/kig.h148
-rw-r--r--kig/kig/kig_commands.cpp398
-rw-r--r--kig/kig/kig_commands.h217
-rw-r--r--kig/kig/kig_document.cc200
-rw-r--r--kig/kig/kig_document.h137
-rw-r--r--kig/kig/kig_iface.cpp31
-rw-r--r--kig/kig/kig_iface.h37
-rw-r--r--kig/kig/kig_part.cpp1041
-rw-r--r--kig/kig/kig_part.desktop16
-rw-r--r--kig/kig/kig_part.h257
-rw-r--r--kig/kig/kig_view.cpp593
-rw-r--r--kig/kig/kig_view.h274
-rw-r--r--kig/kig/kigpartui.rc288
-rw-r--r--kig/kig/kigui.rc40
-rw-r--r--kig/kig/main.cpp144
26 files changed, 4392 insertions, 0 deletions
diff --git a/kig/kig/Makefile.am b/kig/kig/Makefile.am
new file mode 100644
index 00000000..719886cc
--- /dev/null
+++ b/kig/kig/Makefile.am
@@ -0,0 +1,53 @@
+# this has all of the subdirectories that make will recurse into. if
+# there are none, comment this out
+#SUBDIRS = pics icons
+
+# set the include path for X, qt and KDE
+INCLUDES = $(all_includes)
+
+# these are the headers for your project
+noinst_HEADERS = kig.h kig_document.h kig_part.h kig_view.h kig_commands.h
+
+# let automoc handle all of the meta source files (moc)
+METASOURCES = AUTO
+
+KDE_ICON = AUTO
+
+# this Makefile creates both a KPart application and a KPart
+#########################################################################
+# APPLICATION SECTION
+#########################################################################
+# this is the program that gets installed. it's name is used for all
+# of the other Makefile.am variables
+bin_PROGRAMS = kig
+
+# the application source, library search path, and link libraries
+kig_SOURCES = main.cpp kig.cpp
+kig_LDFLAGS = $(KDE_RPATH) $(all_libraries)
+kig_LDADD = $(LIB_KPARTS)
+
+# this is where the desktop file will go
+xdg_apps_DATA = kig.desktop
+
+# this is where the shell's XML-GUI resource file goes
+rcdir = $(kde_datadir)/kig
+rc_DATA = kigui.rc kigpartui.rc
+
+#########################################################################
+# KPART SECTION
+#########################################################################
+noinst_LTLIBRARIES = libkigparttemp.la
+
+# the Part's source, library search path, and link libraries
+libkigparttemp_la_SOURCES = \
+ kig_document.cc \
+ kig_part.cpp \
+ kig_view.cpp \
+ kig_commands.cpp
+
+libkigparttemp_la_LDFLAGS = $(all_libraries)
+libkigparttemp_la_LIBADD = $(LIB_KDEPRINT) $(LIB_KIO)
+
+# this is where the desktop file will go
+partdesktopdir = $(kde_servicesdir)
+partdesktop_DATA = kig_part.desktop
diff --git a/kig/kig/aboutdata.h b/kig/kig/aboutdata.h
new file mode 100644
index 00000000..db4f3689
--- /dev/null
+++ b/kig/kig/aboutdata.h
@@ -0,0 +1,89 @@
+// Copyright (C) 2002 Dominique Devriese <devriese@kde.org>
+
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+// 02110-1301, USA.
+
+#include <kaboutdata.h>
+#include <klocale.h>
+
+#include "config.h"
+
+inline KAboutData* kigAboutData( const char* name, const char* iname )
+{
+ const char* version = "v" KIGVERSION;
+ const char* description = I18N_NOOP( "KDE Interactive Geometry" );
+
+ KAboutData* tmp = new KAboutData( name, iname, version,
+ description, KAboutData::License_GPL,
+ I18N_NOOP( "(C) 2002-2005, The Kig developers" ),
+ 0, "http://edu.kde.org/kig" );
+ tmp->addAuthor("Dominique Devriese",
+ I18N_NOOP("Original author, long time maintainer, design and lots of code."),
+ "devriese@kde.org" );
+
+ tmp->addAuthor("Maurizio Paolini",
+ I18N_NOOP( "Did a lot of important work all around Kig, "
+ "including, but not limited to conics, cubics, "
+ "transformations and property tests support." ),
+ "paolini@dmf.unicatt.it");
+
+ tmp->addAuthor( "Pino Toscano",
+ I18N_NOOP( "Actual maintainer, Dr. Geo import filter, point and "
+ "line styles, Italian translation, "
+ "miscellaneous stuff here and there." ),
+ "toscano.pino@tiscali.it" );
+
+ tmp->addAuthor( "Franco Pasquarelli",
+ I18N_NOOP( "Helped a lot with the implementation of the Locus object, "
+ "there's quite some math involved in doing it right, and "
+ "Franco wrote the most difficult parts." ),
+ "pasqui@dmf.unicatt.it" );
+
+ tmp->addCredit( "Eric Depagne",
+ I18N_NOOP( "The French translator, who also sent me some useful "
+ "feedback, like feature requests and bug reports." ),
+ "edepagne@eso.org" );
+
+ tmp->addCredit("Marc Bartsch",
+ I18N_NOOP("Author of KGeo, where I got inspiration, "
+ "some source, and most of the artwork from." ),
+ "marc.bartsch@web.de");
+
+ tmp->addCredit("Christophe Devriese",
+ I18N_NOOP( "Domi's brother, who he got to write the algorithm for "
+ "calculating the center of the circle with three "
+ "points given." ),
+ "oelewapperke@ulyssis.org" );
+
+ tmp->addCredit("Christophe Prud'homme",
+ I18N_NOOP( "Sent me a patch for some bugs." ),
+ "prudhomm@mit.edu" );
+
+ tmp->addCredit("Robert Gogolok",
+ I18N_NOOP("Gave me some good feedback on Kig, some feature "
+ "requests, cleanups and style fixes, and someone "
+ "to chat with on irc :)" ),
+ "robertgogolok@gmx.de");
+
+ tmp->addCredit("David Vignoni",
+ I18N_NOOP("Responsible for the nice application SVG Icon." ),
+ "david80v@tin.it");
+
+ tmp->addCredit( "Danny Allen",
+ I18N_NOOP( "Responsible for the new object action icons." ),
+ "danny@dannyallen.co.uk" );
+
+ return tmp;
+}
diff --git a/kig/kig/hi128-app-kig.png b/kig/kig/hi128-app-kig.png
new file mode 100644
index 00000000..48eac877
--- /dev/null
+++ b/kig/kig/hi128-app-kig.png
Binary files differ
diff --git a/kig/kig/hi16-app-kig.png b/kig/kig/hi16-app-kig.png
new file mode 100644
index 00000000..67e1d839
--- /dev/null
+++ b/kig/kig/hi16-app-kig.png
Binary files differ
diff --git a/kig/kig/hi22-app-kig.png b/kig/kig/hi22-app-kig.png
new file mode 100644
index 00000000..bb3f7359
--- /dev/null
+++ b/kig/kig/hi22-app-kig.png
Binary files differ
diff --git a/kig/kig/hi32-app-kig.png b/kig/kig/hi32-app-kig.png
new file mode 100644
index 00000000..f7d51c72
--- /dev/null
+++ b/kig/kig/hi32-app-kig.png
Binary files differ
diff --git a/kig/kig/hi48-app-kig.png b/kig/kig/hi48-app-kig.png
new file mode 100644
index 00000000..b28d3b96
--- /dev/null
+++ b/kig/kig/hi48-app-kig.png
Binary files differ
diff --git a/kig/kig/hi64-app-kig.png b/kig/kig/hi64-app-kig.png
new file mode 100644
index 00000000..e9586819
--- /dev/null
+++ b/kig/kig/hi64-app-kig.png
Binary files differ
diff --git a/kig/kig/hisc-app-kig.svgz b/kig/kig/hisc-app-kig.svgz
new file mode 100644
index 00000000..baf0f149
--- /dev/null
+++ b/kig/kig/hisc-app-kig.svgz
Binary files differ
diff --git a/kig/kig/kig.cpp b/kig/kig/kig.cpp
new file mode 100644
index 00000000..2429c843
--- /dev/null
+++ b/kig/kig/kig.cpp
@@ -0,0 +1,308 @@
+/**
+ This file is part of Kig, a KDE program for Interactive Geometry...
+ Copyright (C) 2002 Dominique Devriese <devriese@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ USA
+**/
+
+#include "kig.h"
+#include "kig.moc"
+
+#include <qevent.h>
+#include <qtimer.h>
+
+#include <kaction.h>
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kdebug.h>
+#include <kedittoolbar.h>
+#include <kfiledialog.h>
+#include <kkeydialog.h>
+#include <klibloader.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kstatusbar.h>
+#include <kstdaction.h>
+#include <ktip.h>
+#include <kurl.h>
+#include <kurldrag.h>
+
+#include <assert.h>
+
+Kig::Kig()
+ : KParts::MainWindow( 0L, "Kig" ), m_part( 0 )
+{
+ // setting the configation file
+ config = new KConfig( "kigrc" );
+ // set the shell's ui resource file
+ setXMLFile("kigui.rc");
+ // then, setup our actions
+ setupActions();
+
+ // this routine will find and load our Part. it finds the Part by
+ // name which is a bad idea usually.. but it's alright in this
+ // case since our Part is made for this Shell
+
+ // we use globalLibrary() because if we use python scripting, then
+ // we need the python symbols to be exported, in order for python to
+ // be able to load its dll modules.. Another part of the problem is
+ // that boost.python fails to link against python ( on Debian at
+ // least ).
+ KLibrary* library = KLibLoader::self()->globalLibrary("libkigpart");
+ KLibFactory* factory = 0;
+ if ( library ) factory = library->factory();
+ if (factory)
+ {
+ // now that the Part is loaded, we cast it to a Part to get
+ // our hands on it
+ m_part = static_cast<KParts::ReadWritePart*>
+ (factory->create(this, "kig_part", "KParts::ReadWritePart" ));
+ if (m_part)
+ {
+ // tell the KParts::MainWindow that this is indeed the main widget
+ setCentralWidget(m_part->widget());
+
+ // and integrate the part's GUI with the shell's
+ createGUI(m_part);
+ // finally show tip-of-day ( if the user wants it :) )
+ QTimer::singleShot( 0, this, SLOT( startupTipOfDay() ) );
+ }
+ }
+ else
+ {
+ // if we couldn't find our Part, we exit since the Shell by
+ // itself can't do anything useful
+ KMessageBox::error(this, i18n( "Could not find the necessary Kig library, check your installation." ) );
+ KApplication::exit();
+ return;
+ }
+
+ // we have drag'n'drop
+ setAcceptDrops(true);
+
+ // save the window settings on exit.
+ setAutoSaveSettings();
+}
+
+Kig::~Kig()
+{
+ m_recentFilesAction->saveEntries(config);
+ delete config;
+}
+
+void Kig::setupActions()
+{
+ KStdAction::openNew(this, SLOT(fileNew()), actionCollection());
+ KStdAction::open(this, SLOT(fileOpen()), actionCollection());
+ KStdAction::quit(this, SLOT(close()), actionCollection());
+
+#ifdef KIG_DONT_USE_NEW_KMAINWINDOW_FEATURES
+ m_toolbarAction = KStdAction::showToolbar(this, SLOT(optionsShowToolbar()), actionCollection());
+ m_statusbarAction = KStdAction::showStatusbar(this, SLOT(optionsShowStatusbar()), actionCollection());
+#else
+ createStandardStatusBarAction();
+ setStandardToolBarMenuEnabled(true);
+#endif
+
+ // FIXME: this (recent files) should be app-wide, not specific to each window...
+ m_recentFilesAction = KStdAction::openRecent(this, SLOT(openURL(const KURL&)), actionCollection());
+ m_recentFilesAction->loadEntries(config);
+
+#if KDE_IS_VERSION( 3, 2, 90 )
+ KStdAction::keyBindings( guiFactory(), SLOT( configureShortcuts() ), actionCollection() );
+#else
+ KStdAction::keyBindings(this, SLOT(optionsConfigureKeys()), actionCollection());
+#endif
+ KStdAction::configureToolbars(this, SLOT(optionsConfigureToolbars()), actionCollection());
+
+ KStdAction::tipOfDay( this, SLOT( tipOfDay() ), actionCollection(), "help_tipofday" );
+}
+
+void Kig::saveProperties(KConfig* config)
+{
+ // the 'config' object points to the session managed
+ // config file. anything you write here will be available
+ // later when this app is restored
+ config->writePathEntry("fileName", m_part->url().path());
+}
+
+void Kig::readProperties(KConfig* config)
+{
+ // the 'config' object points to the session managed
+ // config file. this function is automatically called whenever
+ // the app is being restored. read in here whatever you wrote
+ // in 'saveProperties'
+ load ( KURL(config->readPathEntry("fileName")));
+}
+
+void Kig::load(const KURL& url)
+{
+ // we check for m_part not being 0, because in the case of us not
+ // finding our library, we would otherwise get a crash...
+ if ( m_part && m_part->openURL( url ) ) m_recentFilesAction->addURL( url );
+}
+
+void Kig::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
+
+ // create a new window if we aren't in the "initial state" ( see
+ // the KDE style guide on the file menu stuff...)
+ if ( ! m_part->url().isEmpty() || m_part->isModified() )
+ (new Kig)->show();
+}
+
+void Kig::openURL(const KURL& url)
+{
+ // Called for opening a file by either the KRecentFilesAction or our
+ // own fileOpen() method.
+ // if we are in the "initial state", we open the url in this window:
+ if ( m_part->url().isEmpty() && ! m_part->isModified() )
+ {
+ load( url );
+ }
+ else
+ {
+ // otherwise we open it in a new window...
+ Kig* widget = new Kig;
+ widget->load(url);
+ widget->show();
+ };
+}
+
+void Kig::optionsConfigureKeys()
+{
+#if KDE_IS_VERSION( 3, 2, 90 )
+ assert( false );
+#else
+ KKeyDialog dlg( true, this );
+ dlg.insert( actionCollection() );
+ dlg.insert( m_part->actionCollection() );
+ (void) dlg.configure( true );
+#endif
+}
+
+void Kig::optionsConfigureToolbars()
+{
+ saveMainWindowSettings(KGlobal::config(), "MainWindow");
+
+ // use the standard toolbar editor
+ KEditToolbar dlg(factory());
+ connect(&dlg, SIGNAL(newToolbarConfig()),
+ this, SLOT(applyNewToolbarConfig()));
+ dlg.exec();
+}
+
+void Kig::applyNewToolbarConfig()
+{
+ applyMainWindowSettings(KGlobal::config(), "MainWindow");
+}
+
+bool Kig::queryClose()
+{
+ if (!m_part->isReadWrite() || !m_part->isModified()) return true;
+ switch( KMessageBox::warningYesNoCancel
+ (
+ widget(),
+ i18n("Save changes to document %1?").arg(m_part->url().path()),
+ i18n("Save Changes?"),KStdGuiItem::save(),KStdGuiItem::discard()
+ ))
+ {
+ case KMessageBox::Yes:
+ if (m_part->save()) return true;
+ else return false;
+ break;
+ case KMessageBox::No:
+ return true;
+ break;
+ default: // cancel
+ return false;
+ break;
+ };
+}
+
+void Kig::dragEnterEvent(QDragEnterEvent* e)
+{
+ e->accept(KURLDrag::canDecode(e));
+}
+
+void Kig::dropEvent(QDropEvent* e)
+{
+ KURL::List urls;
+ if ( KURLDrag::decode (e, urls) )
+ {
+ for (KURL::List::iterator u = urls.begin(); u != urls.end(); ++u)
+ {
+ Kig* k = new Kig;
+ k->show();
+ k->load(*u);
+ };
+ };
+}
+
+void Kig::fileOpen()
+{
+ QString formats =
+ i18n( "*.kig *.kigz *.kgeo *.seg|All Supported Files (*.kig *.kigz *.kgeo *.seg)\n"
+ "*.kig|Kig Documents (*.kig)\n"
+ "*.kigz|Compressed Kig Documents (*.kigz)\n"
+ "*.kgeo|KGeo Documents (*.kgeo)\n"
+ "*.seg|KSeg Documents (*.seg)\n"
+ "*.fgeo|Dr. Geo Documents (*.fgeo)\n"
+ "*.fig *.FIG|Cabri Documents (*.fig *.FIG)" );
+
+ // this slot is connected to the KStdAction::open action...
+ QString file_name = KFileDialog::getOpenFileName(":document", formats );
+
+ if (!file_name.isEmpty()) openURL(file_name);
+}
+
+// ifdef's disabled, cause Qt moc doesn't handle ifdef's..
+// #ifdef KIG_DONT_USE_NEW_KMAINWINDOW_FEATURES
+void Kig::optionsShowToolbar()
+{
+#ifdef KIG_DONT_USE_NEW_KMAINWINDOW_FEATURES
+ if (m_toolbarAction->isChecked())
+ toolBar()->show();
+ else
+ toolBar()->hide();
+#else
+ assert( false );
+#endif
+}
+
+void Kig::optionsShowStatusbar()
+{
+#ifdef KIG_DONT_USE_NEW_KMAINWINDOW_FEATURES
+ if (m_statusbarAction->isChecked())
+ statusBar()->show();
+ else
+ statusBar()->hide();
+#else
+ assert( false );
+#endif
+}
+// #endif
+
+void Kig::tipOfDay() {
+ KTipDialog::showTip( "kig/tips", true );
+}
+
+void Kig::startupTipOfDay() {
+ KTipDialog::showTip( "kig/tips" );
+}
diff --git a/kig/kig/kig.desktop b/kig/kig/kig.desktop
new file mode 100644
index 00000000..b2e11e40
--- /dev/null
+++ b/kig/kig/kig.desktop
@@ -0,0 +1,121 @@
+[Desktop Entry]
+Name=Kig
+Name[bn]=কিগ
+Name[hi]=केआईजी
+Name[ne]=किग
+Name[pa]=ਕਿਗ
+Name[ta]=கிக்
+GenericName=Interactive Geometry
+GenericName[af]=Interaktiewe Meetkunde
+GenericName[be]=Інтэрактыўная геаметрыя
+GenericName[bg]=Интерактивна геометрия
+GenericName[bn]=ইন্টারঅ্যাকটিভ জ্যামিতি
+GenericName[bs]=Interaktivna geometrija
+GenericName[ca]=Geometria interactiva
+GenericName[cs]=Interaktivní geometrie
+GenericName[csb]=Interaktiwnô geòmetrëjô
+GenericName[cy]=Geometreg Rhyngweithiol
+GenericName[da]=Interaktiv geometri
+GenericName[de]=Interaktive Geometrie
+GenericName[el]=Aλληλεπιδραστική γεωμετρία
+GenericName[eo]=Interaga geometrios
+GenericName[es]=Geometría interactiva
+GenericName[et]=Interaktiivne geomeetria
+GenericName[eu]=Geometria interaktiboa
+GenericName[fa]=هندسۀ تعاملی
+GenericName[fi]=Interaktiivinen Geometria
+GenericName[fr]=Géométrie interactive
+GenericName[ga]=Céimseata Idirghníomhach
+GenericName[gl]=Xeometría Interactiva
+GenericName[he]=גאומטריה אינטראקטיבית
+GenericName[hi]=इंटरएक्टिव ज्यॉमिती
+GenericName[hr]=Interaktivna geometrija
+GenericName[hu]=Interaktív geometria
+GenericName[is]=Gagnvirk rúmfræði
+GenericName[it]=Geometria interattiva
+GenericName[ja]=幾何学との対話
+GenericName[ka]=ინტერაქტიური გეომეტრია
+GenericName[km]=ធរណីមាត្រ​អន្តរកម្ម
+GenericName[lt]=Interaktyvi geometrija
+GenericName[ms]=Geometri Interaktif
+GenericName[nb]=Interaktiv geometri
+GenericName[nds]=Wesselwarken Geometrie
+GenericName[ne]=अन्तर्क्रियात्मक भूगोल
+GenericName[nl]=Interactieve geometry
+GenericName[nn]=Interaktiv geometri
+GenericName[pa]=ਦਿਲ-ਖਿਚਵੀਂ ਜੁਮੈਟਰੀ
+GenericName[pl]=Interaktywna geometria
+GenericName[pt]=Geometria Interactiva
+GenericName[pt_BR]=Geometria interativa
+GenericName[ru]=Интерактивная геометрия
+GenericName[sk]=Interaktívna geometria
+GenericName[sl]=Interaktivna geometrija
+GenericName[sr]=Интерактивна геометрија
+GenericName[sr@Latn]=Interaktivna geometrija
+GenericName[sv]=Interaktiv geometri
+GenericName[ta]= ஊடாடும் வடிவியல்
+GenericName[tg]=Геометрияи интерактивӣ
+GenericName[tr]=Etkileşimli Geometri
+GenericName[uk]=Інтерактивна геометрія
+GenericName[ven]=Geometry yau shumea nayo
+GenericName[vi]=Hình học Tương tác
+GenericName[xh]=Umyili Wesiboniso Esingaphakathi
+GenericName[zh_CN]=交互几何
+GenericName[zh_TW]=交互式幾何作圖
+GenericName[zu]=Ukubekeka Kwebalazwe Kokukhulumisanayo
+Comment=Explore Geometric Constructions
+Comment[be]=Вывучэнне геаметрычных фігур
+Comment[bg]=Геометрични конструкции
+Comment[bn]=জ্যামিতি ছবি আঁকা চর্চা করুন
+Comment[bs]=Istražite geometrijske konstrukcije
+Comment[ca]=Explora construccions geomètriques
+Comment[cs]=Objevujte geometrické konstrukce
+Comment[csb]=Exploatëjë geòmetriczne kònstrukcëjë
+Comment[da]=Udforsk geometriske konstruktioner
+Comment[de]=Geometrische Konstruktionen untersuchen
+Comment[el]=Εξερεύνηση γεωμετρικών κατασκευών
+Comment[eo]=Explorado de geometriaj konstruaĵoj
+Comment[es]=Exploración de construcciones geométricas
+Comment[et]=Geomeetriliste kujundite tundmaõppimine
+Comment[eu]=Arakatu geometria egiturak
+Comment[fa]=کاوش ساختارهای هندسی
+Comment[fi]=Tutki geometrisia rakenteita
+Comment[fr]=Explorer les constructions géométriques
+Comment[ga]=Taiscéal Tógálacha Céimseatúla
+Comment[gl]=Explore as Figuras Xeométricas
+Comment[he]=חקור מבנים גאומטריים
+Comment[hr]=Upoznajte geometrijske konstrukcije
+Comment[hu]=Geometriai oktatóprogram
+Comment[is]=Kanna rúmfræðilega byggingu forma
+Comment[it]=Esplora le costruzioni geometriche
+Comment[ja]=幾何学との対話
+Comment[ka]=გეომეტრიულ ფიგურათა შესწავლა
+Comment[km]=រុករក​សំណង់​ធរណីមាត្រ
+Comment[lt]=Geometrinių konstrukcijų tyrinėjimas
+Comment[ms]=Jelahan Pembinaan Geometrik
+Comment[nb]=Utforsk geometriske konstruksjoner
+Comment[nds]=Geometersch Konstrukschonen bekieken
+Comment[ne]=भूगोल बनावट अन्वेषण गर्नुहोस्
+Comment[nl]=Ruimtelijke constructies verkennen
+Comment[nn]=Utforsk geometriske konstruksjonar
+Comment[pl]=Zabawa konstrukcjami geometrycznymi
+Comment[pt]=Explorar Construções Geométricas
+Comment[pt_BR]=Explore construções geométricas
+Comment[ru]=Работа с геометрическими построениями
+Comment[sk]=Prieskum geometrických konštrukcií
+Comment[sl]=Raziskovanje geometrijskih konstrukcij
+Comment[sr]=Истражујте геометријске конструкције
+Comment[sr@Latn]=Istražujte geometrijske konstrukcije
+Comment[sv]=Utforska geometriska konstruktioner
+Comment[tr]=Geometik Şekilleri Keşfedin
+Comment[uk]=Дослідження геометричних конструкцій
+Comment[vi]=Khám phá các phép Dụng Hình học
+Comment[zh_CN]=探索几何构造的世界
+Comment[zh_TW]=作出幾何圖形
+Exec=kig %i %m -caption "%c"
+MimeType=application/x-kig;application/x-kgeo;
+Icon=kig
+Type=Application
+DocPath=kig/index.html
+Terminal=false
+Categories=Qt;KDE;Education;Math;
diff --git a/kig/kig/kig.h b/kig/kig/kig.h
new file mode 100644
index 00000000..d6ad9fea
--- /dev/null
+++ b/kig/kig/kig.h
@@ -0,0 +1,148 @@
+// This file is part of Kig, a KDE program for Interactive Geometry...
+// Copyright (C) 2002 Dominique Devriese <devriese@kde.org>
+
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+// 02110-1301, USA.
+
+#ifndef KIG_KIG_H
+#define KIG_KIG_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <kdeversion.h>
+
+#ifdef KDE_IS_VERSION
+#if KDE_IS_VERSION( 3, 1, 90 )
+#undef KIG_DONT_USE_NEW_KMAINWINDOW_FEATURES
+#else
+#define KIG_DONT_USE_NEW_KMAINWINDOW_FEATURES
+#endif
+#else
+#define KIG_DONT_USE_NEW_KMAINWINDOW_FEATURES
+#endif
+
+#include <kapplication.h>
+#include <kparts/mainwindow.h>
+#include <dcopclient.h>
+
+class KToggleAction;
+class KRecentFilesAction;
+
+/**
+ * This is the application "Shell". It has a menubar, toolbar, and
+ * statusbar but relies on the "Part" to do all the real work.
+ */
+class Kig : public KParts::MainWindow
+{
+ Q_OBJECT
+ public:
+ /**
+ * Default Constructor
+ */
+ Kig();
+
+ /**
+ * Default Destructor
+ */
+ virtual ~Kig();
+
+ public slots:
+ /**
+ * Open file in this window
+ * \param file file to open
+ */
+ void load (const KURL& file);
+
+ /**
+ * this opens the file specified in \p s in a new window
+ *
+ * \param s the url of the file to open
+ */
+ void openURL (const QString& s) { openURL(KURL(s)); }
+ void openURL (const KURL& s);
+
+ protected:
+
+ /**
+ * The user started dragging something onto us...
+ *
+ * \param e
+ */
+ void dragEnterEvent(QDragEnterEvent* e);
+
+ /**
+ * The user dropped something onto us...
+ *
+ * \param e
+ */
+ void dropEvent (QDropEvent* e);
+
+ /**
+ * this is called by the framework before closing the window, to
+ * allow the user to save his changes... returning false cancels the
+ * close request...
+ */
+ bool queryClose();
+
+ /**
+ * This method is called when it is time for the app to save its
+ * properties for session management purposes.
+ */
+ void saveProperties(KConfig *);
+
+ /**
+ * This method is called when this app is restored. The KConfig
+ * object points to the session management config file that was saved
+ * with \ref saveProperties
+ */
+ void readProperties(KConfig *);
+
+ private slots:
+ void fileNew();
+ void fileOpen();
+ // Qt moc doesn't handle ifdef's, so i'm disabling it..
+// #ifdef KIG_DONT_USE_NEW_KMAINWINDOW_FEATURES
+ void optionsShowToolbar();
+ void optionsShowStatusbar();
+// #endif
+// #if KDE_IS_VERSION( 3, 2, 90 )
+ void optionsConfigureKeys();
+// #endif
+ void optionsConfigureToolbars();
+
+ void applyNewToolbarConfig();
+
+ void tipOfDay();
+ void startupTipOfDay();
+
+ private:
+ void setupActions();
+
+ KParts::ReadWritePart *m_part;
+
+//#ifdef KIG_DONT_USE_NEW_KMAINWINDOW_FEATURES
+ KToggleAction *m_toolbarAction;
+ KToggleAction *m_statusbarAction;
+//#endif
+ KRecentFilesAction *m_recentFilesAction;
+
+ KConfig* config;
+
+ static bool kimageioRegistered;
+};
+
+#endif // KIG_KIG_H
diff --git a/kig/kig/kig_commands.cpp b/kig/kig/kig_commands.cpp
new file mode 100644
index 00000000..b9846fa6
--- /dev/null
+++ b/kig/kig/kig_commands.cpp
@@ -0,0 +1,398 @@
+/**
+ This file is part of Kig, a KDE program for Interactive Geometry...
+ Copyright (C) 2002 Dominique Devriese <devriese@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ USA
+**/
+
+#include "kig_commands.h"
+#include "kig_commands.moc"
+
+#include "kig_part.h"
+#include "kig_document.h"
+#include "kig_view.h"
+
+#include "../modes/mode.h"
+#include "../objects/object_imp.h"
+#include "../objects/object_drawer.h"
+#include "../misc/calcpaths.h"
+#include "../misc/coordinate_system.h"
+
+#include <vector>
+
+using std::vector;
+using std::max;
+using std::min;
+
+class KigCommand::Private
+{
+public:
+ Private( KigPart& d ) : doc( d ) {}
+ KigPart& doc;
+ vector<KigCommandTask*> tasks;
+};
+
+KigCommand::KigCommand( KigPart& doc, const QString& name )
+ : KNamedCommand(name), d( new Private( doc ) )
+{
+}
+
+KigCommand::~KigCommand()
+{
+ for ( uint i = 0; i < d->tasks.size(); ++i )
+ delete d->tasks[i];
+ delete d;
+}
+
+void KigCommand::execute()
+{
+ for ( uint i = 0; i < d->tasks.size(); ++i )
+ d->tasks[i]->execute( d->doc );
+ d->doc.redrawScreen();
+}
+
+void KigCommand::unexecute()
+{
+ for ( uint i = 0; i < d->tasks.size(); ++i )
+ d->tasks[i]->unexecute( d->doc );
+ d->doc.redrawScreen();
+}
+
+void KigCommand::addTask( KigCommandTask* t )
+{
+ d->tasks.push_back( t );
+}
+
+KigCommand* KigCommand::removeCommand( KigPart& doc, ObjectHolder* o )
+{
+ std::vector<ObjectHolder*> os;
+ os.push_back( o );
+ return removeCommand( doc, os );
+}
+
+KigCommand* KigCommand::addCommand( KigPart& doc, ObjectHolder* o )
+{
+ std::vector<ObjectHolder*> os;
+ os.push_back( o );
+ return addCommand( doc, os );
+}
+
+KigCommand* KigCommand::removeCommand( KigPart& doc, const std::vector<ObjectHolder*>& os )
+{
+ assert( os.size() > 0 );
+ QString text;
+ if ( os.size() == 1 )
+ text = os.back()->imp()->type()->removeAStatement();
+ else
+ text = i18n( "Remove %1 Objects" ).arg( os.size() );
+ KigCommand* ret = new KigCommand( doc, text );
+ ret->addTask( new RemoveObjectsTask( os ) );
+ return ret;
+}
+
+KigCommand* KigCommand::addCommand( KigPart& doc, const std::vector<ObjectHolder*>& os )
+{
+ QString text;
+ if ( os.size() == 1 )
+ text = os.back()->imp()->type()->addAStatement();
+ else
+ text = i18n( "Add %1 Objects" ).arg( os.size() );
+ KigCommand* ret = new KigCommand( doc, text );
+ ret->addTask( new AddObjectsTask( os ) );
+ return ret;
+}
+
+KigCommand* KigCommand::changeCoordSystemCommand( KigPart& doc, CoordinateSystem* s )
+{
+ QString text = CoordinateSystemFactory::setCoordinateSystemStatement( s->id() );
+ KigCommand* ret = new KigCommand( doc, text );
+ ret->addTask( new ChangeCoordSystemTask( s ) );
+ return ret;
+}
+
+KigCommandTask::KigCommandTask()
+{
+}
+
+KigCommandTask::~KigCommandTask()
+{
+}
+
+AddObjectsTask::AddObjectsTask( const std::vector<ObjectHolder*>& os)
+ : KigCommandTask(), undone( true ), mobjs( os )
+{
+}
+
+void AddObjectsTask::execute( KigPart& doc )
+{
+ doc._addObjects( mobjs );
+ undone = false;
+}
+
+void AddObjectsTask::unexecute( KigPart& doc )
+{
+ doc._delObjects( mobjs );
+ undone = true;
+}
+
+AddObjectsTask::~AddObjectsTask()
+{
+ if ( undone )
+ for ( std::vector<ObjectHolder*>::iterator i = mobjs.begin();
+ i != mobjs.end(); ++i )
+ delete *i;
+}
+
+RemoveObjectsTask::RemoveObjectsTask( const std::vector<ObjectHolder*>& os )
+ : AddObjectsTask( os )
+{
+ undone = false;
+}
+
+void RemoveObjectsTask::execute( KigPart& doc )
+{
+ AddObjectsTask::unexecute( doc );
+}
+
+void RemoveObjectsTask::unexecute( KigPart& doc )
+{
+ AddObjectsTask::execute( doc );
+}
+
+ChangeObjectConstCalcerTask::ChangeObjectConstCalcerTask( ObjectConstCalcer* calcer, ObjectImp* newimp )
+ : KigCommandTask(), mcalcer( calcer ), mnewimp( newimp )
+{
+}
+
+void ChangeObjectConstCalcerTask::execute( KigPart& doc )
+{
+ mnewimp = mcalcer->switchImp( mnewimp );
+
+ std::set<ObjectCalcer*> allchildren = getAllChildren( mcalcer.get() );
+ std::vector<ObjectCalcer*> allchildrenvect( allchildren.begin(), allchildren.end() );
+ allchildrenvect = calcPath( allchildrenvect );
+ for ( std::vector<ObjectCalcer*>::iterator i = allchildrenvect.begin();
+ i != allchildrenvect.end(); ++i )
+ ( *i )->calc( doc.document() );
+}
+
+void ChangeObjectConstCalcerTask::unexecute( KigPart& doc )
+{
+ execute( doc );
+}
+
+struct MoveDataStruct
+{
+ ObjectConstCalcer* o;
+ ObjectImp* oldimp;
+ MoveDataStruct( ObjectConstCalcer* io, ObjectImp* oi )
+ : o( io ), oldimp( oi ) { }
+};
+
+class MonitorDataObjects::Private
+{
+public:
+ vector<MoveDataStruct> movedata;
+};
+
+MonitorDataObjects::MonitorDataObjects( const std::vector<ObjectCalcer*>& objs )
+ : d( new Private )
+{
+ monitor( objs );
+}
+
+void MonitorDataObjects::monitor( const std::vector<ObjectCalcer*>& objs )
+{
+ for ( std::vector<ObjectCalcer*>::const_iterator i = objs.begin(); i != objs.end(); ++i )
+ if ( dynamic_cast<ObjectConstCalcer*>( *i ) )
+ {
+ MoveDataStruct n( static_cast<ObjectConstCalcer*>( *i ), (*i)->imp()->copy() );
+ d->movedata.push_back( n );
+ };
+}
+
+void MonitorDataObjects::finish( KigCommand* comm )
+{
+ for ( uint i = 0; i < d->movedata.size(); ++i )
+ {
+ ObjectConstCalcer* o = d->movedata[i].o;
+ if ( ! d->movedata[i].oldimp->equals( *o->imp() ) )
+ {
+ ObjectImp* newimp = o->switchImp( d->movedata[i].oldimp );
+ comm->addTask( new ChangeObjectConstCalcerTask( o, newimp ) );
+ }
+ else
+ delete d->movedata[i].oldimp;
+ };
+ d->movedata.clear();
+}
+
+MonitorDataObjects::~MonitorDataObjects()
+{
+ assert( d->movedata.empty() );
+ delete d;
+}
+
+ChangeCoordSystemTask::ChangeCoordSystemTask( CoordinateSystem* s )
+ : KigCommandTask(), mcs( s )
+{
+}
+
+void ChangeCoordSystemTask::execute( KigPart& doc )
+{
+ mcs = doc.document().switchCoordinateSystem( mcs );
+ std::vector<ObjectCalcer*> calcpath = calcPath( getAllCalcers( doc.document().objects() ) );
+ for ( std::vector<ObjectCalcer*>::iterator i = calcpath.begin(); i != calcpath.end(); ++i )
+ ( *i )->calc( doc.document() );
+ doc.coordSystemChanged( doc.document().coordinateSystem().id() );
+}
+
+void ChangeCoordSystemTask::unexecute( KigPart& doc )
+{
+ execute( doc );
+}
+
+ChangeCoordSystemTask::~ChangeCoordSystemTask()
+{
+ delete mcs;
+}
+
+class ChangeParentsAndTypeTask::Private
+{
+public:
+ ObjectTypeCalcer* o;
+ std::vector<ObjectCalcer::shared_ptr> newparents;
+ const ObjectType* newtype;
+};
+
+ChangeParentsAndTypeTask::~ChangeParentsAndTypeTask()
+{
+ delete d;
+}
+
+ChangeParentsAndTypeTask::ChangeParentsAndTypeTask(
+ ObjectTypeCalcer* o, const std::vector<ObjectCalcer*>& newparents,
+ const ObjectType* newtype )
+ : KigCommandTask(), d( new Private )
+{
+ d->o = o;
+ std::copy( newparents.begin(), newparents.end(),
+ std::back_inserter( d->newparents ) );
+ d->newtype = newtype;
+}
+
+void ChangeParentsAndTypeTask::execute( KigPart& doc )
+{
+ const ObjectType* oldtype = d->o->type();
+ d->o->setType( d->newtype );
+ d->newtype = oldtype;
+
+ std::vector<ObjectCalcer*> oldparentso = d->o->parents();
+ std::vector<ObjectCalcer::shared_ptr> oldparents(
+ oldparentso.begin(), oldparentso.end() );
+ std::vector<ObjectCalcer*> newparents;
+ for ( std::vector<ObjectCalcer::shared_ptr>::iterator i = d->newparents.begin();
+ i != d->newparents.end(); ++i )
+ newparents.push_back( i->get() );
+ d->o->setParents( newparents );
+ d->newparents = oldparents;
+
+ for ( std::vector<ObjectCalcer*>::iterator i = newparents.begin(); i != newparents.end(); ++i )
+ ( *i )->calc( doc.document() );
+ d->o->calc( doc.document() );
+ std::set<ObjectCalcer*> allchildren = getAllChildren( d->o );
+ std::vector<ObjectCalcer*> allchildrenvect( allchildren.begin(), allchildren.end() );
+ allchildrenvect = calcPath( allchildrenvect );
+ for ( std::vector<ObjectCalcer*>::iterator i = allchildrenvect.begin();
+ i != allchildrenvect.end(); ++i )
+ ( *i )->calc( doc.document() );
+}
+
+void ChangeParentsAndTypeTask::unexecute( KigPart& doc )
+{
+ execute( doc );
+}
+
+class KigViewShownRectChangeTask::Private
+{
+public:
+ Private( KigWidget& view, const Rect& r ) : v( view ), rect( r ) { }
+ KigWidget& v;
+ Rect rect;
+};
+
+KigViewShownRectChangeTask::KigViewShownRectChangeTask(
+ KigWidget& v, const Rect& newrect )
+ : KigCommandTask()
+{
+ d = new Private( v, newrect );
+}
+
+KigViewShownRectChangeTask::~KigViewShownRectChangeTask()
+{
+ delete d;
+}
+
+void KigViewShownRectChangeTask::execute( KigPart& doc )
+{
+ Rect oldrect = d->v.showingRect();
+ d->v.setShowingRect( d->rect );
+ doc.mode()->redrawScreen( &d->v );
+ d->v.updateScrollBars();
+ d->rect = oldrect;
+}
+
+void KigViewShownRectChangeTask::unexecute( KigPart& doc )
+{
+ execute( doc );
+}
+
+ChangeObjectDrawerTask::~ChangeObjectDrawerTask()
+{
+ delete mnewdrawer;
+}
+
+ChangeObjectDrawerTask::ChangeObjectDrawerTask(
+ ObjectHolder* holder, ObjectDrawer* newdrawer )
+ : KigCommandTask(), mholder( holder ), mnewdrawer( newdrawer )
+{
+}
+
+void ChangeObjectDrawerTask::execute( KigPart& )
+{
+ mnewdrawer = mholder->switchDrawer( mnewdrawer );
+}
+
+void ChangeObjectDrawerTask::unexecute( KigPart& doc )
+{
+ execute( doc );
+}
+
+MonitorDataObjects::MonitorDataObjects( ObjectCalcer* c )
+ : d( new Private )
+{
+ if ( dynamic_cast<ObjectConstCalcer*>( c ) )
+ {
+ MoveDataStruct n( static_cast<ObjectConstCalcer*>( c ), c->imp()->copy() );
+ d->movedata.push_back( n );
+ };
+}
+
+ChangeObjectConstCalcerTask::~ChangeObjectConstCalcerTask()
+{
+ delete mnewimp;
+}
+
diff --git a/kig/kig/kig_commands.h b/kig/kig/kig_commands.h
new file mode 100644
index 00000000..8e4fd044
--- /dev/null
+++ b/kig/kig/kig_commands.h
@@ -0,0 +1,217 @@
+/*
+ This file is part of Kig, a KDE program for Interactive Geometry...
+ Copyright (C) 2002 Dominique Devriese <devriese@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ USA
+*/
+
+
+#ifndef KIG_COMMANDS_H
+#define KIG_COMMANDS_H
+
+#include <kcommand.h>
+#include <klocale.h>
+#include <kdebug.h>
+
+#include "../objects/object_holder.h"
+
+class KigDocument;
+class KigPart;
+class CoordinateSystem;
+
+class KigCommandTask;
+class KigWidget;
+class Rect;
+
+/**
+ * a KigCommand represents almost every action performed in Kig.
+ * Used mainly in the Undo/Redo stuff...
+ */
+class KigCommand
+ : public QObject, public KNamedCommand
+{
+ Q_OBJECT
+ class Private;
+ Private* d;
+public:
+ KigCommand( KigPart& inDoc, const QString& name );
+ ~KigCommand();
+
+ /**
+ * To avoid confusion, this doesn't add a command to anything, this
+ * creates an AddCommand ;)
+ */
+ static KigCommand* addCommand( KigPart& doc, const std::vector<ObjectHolder*>& os );
+ static KigCommand* addCommand( KigPart& doc, ObjectHolder* os );
+ /**
+ * make sure that when you delete something, you are also deleting
+ * its parents. This class assumes you've done that.
+ * \ref KigDocument::delObjects() takes care of this for you.
+ */
+ static KigCommand* removeCommand( KigPart& doc, const std::vector<ObjectHolder*>& os );
+ static KigCommand* removeCommand( KigPart& doc, ObjectHolder* o );
+
+ static KigCommand* changeCoordSystemCommand( KigPart& doc, CoordinateSystem* s );
+
+ void addTask( KigCommandTask* );
+
+ void execute();
+ void unexecute();
+};
+
+class KigCommandTask
+{
+public:
+ KigCommandTask();
+ virtual ~KigCommandTask();
+
+ virtual void execute( KigPart& doc ) = 0;
+ virtual void unexecute( KigPart& doc ) = 0;
+};
+
+class AddObjectsTask
+ : public KigCommandTask
+{
+public:
+ AddObjectsTask( const std::vector<ObjectHolder*>& os);
+ ~AddObjectsTask ();
+ void execute( KigPart& doc );
+ void unexecute( KigPart& doc );
+protected:
+ bool undone;
+
+ std::vector<ObjectHolder*> mobjs;
+};
+
+class RemoveObjectsTask
+ : public AddObjectsTask
+{
+public:
+ RemoveObjectsTask( const std::vector<ObjectHolder*>& os );
+ void execute( KigPart& );
+ void unexecute( KigPart& );
+};
+
+class ChangeObjectConstCalcerTask
+ : public KigCommandTask
+{
+public:
+ ChangeObjectConstCalcerTask( ObjectConstCalcer* calcer, ObjectImp* newimp );
+ ~ChangeObjectConstCalcerTask();
+
+ void execute( KigPart& );
+ void unexecute( KigPart& );
+protected:
+ ObjectConstCalcer::shared_ptr mcalcer;
+ ObjectImp* mnewimp;
+};
+
+/**
+ * this class monitors a set of DataObjects for changes and returns an
+ * appropriate ChangeObjectImpsCommand if necessary..
+ * E.g. MovingMode wants to move certain objects, so it monitors all
+ * the parents of the explicitly moving objects:
+ * \code
+ * MonitorDataObjects mon( getAllParents( emo ) );
+ * \endcode
+ * It then moves them around, and when it is finished, it asks to add
+ * the KigCommandTasks to a KigCommand, and applies that..
+ * \code
+ * KigCommand* comm = new KigCommand( doc, i18n( "Move Stuff" ) );
+ * mon.finish( comm );
+ * \endcode
+ */
+class MonitorDataObjects
+{
+ class Private;
+ Private* d;
+public:
+ /**
+ * all the DataObjects in \p objs will be watched..
+ */
+ MonitorDataObjects( const std::vector<ObjectCalcer*>& objs );
+ MonitorDataObjects( ObjectCalcer* c );
+ ~MonitorDataObjects();
+
+ /**
+ * add \p objs to the list of objs to be watched, and save their
+ * current imp's..
+ */
+ void monitor( const std::vector<ObjectCalcer*>& objs );
+
+ /**
+ * add the generated KigCommandTasks to the command \p comm ..
+ * monitoring stops after this is called..
+ */
+ void finish( KigCommand* comm );
+};
+
+class ChangeCoordSystemTask
+ : public KigCommandTask
+{
+ CoordinateSystem* mcs;
+public:
+ /**
+ * a command that changes the coordinate-system to \p s ..
+ */
+ ChangeCoordSystemTask( CoordinateSystem* s );
+ ~ChangeCoordSystemTask();
+
+ void execute( KigPart& doc );
+ void unexecute( KigPart& doc );
+};
+
+class ChangeParentsAndTypeTask
+ : public KigCommandTask
+{
+ class Private;
+ Private* d;
+public:
+ ChangeParentsAndTypeTask( ObjectTypeCalcer* o, const std::vector<ObjectCalcer*>& newparents,
+ const ObjectType* newtype );
+ ~ChangeParentsAndTypeTask();
+
+ void execute( KigPart& doc );
+ void unexecute( KigPart& doc );
+};
+
+class KigViewShownRectChangeTask
+ : public KigCommandTask
+{
+ class Private;
+ Private* d;
+public:
+ KigViewShownRectChangeTask( KigWidget& v, const Rect& newrect );
+ ~KigViewShownRectChangeTask();
+
+ void execute( KigPart& doc );
+ void unexecute( KigPart& doc );
+};
+
+class ChangeObjectDrawerTask
+ : public KigCommandTask
+{
+ ObjectHolder* mholder;
+ ObjectDrawer* mnewdrawer;
+public:
+ ChangeObjectDrawerTask( ObjectHolder* holder, ObjectDrawer* newdrawer );
+ ~ChangeObjectDrawerTask();
+
+ void execute( KigPart& doc );
+ void unexecute( KigPart& doc );
+};
+
+#endif
diff --git a/kig/kig/kig_document.cc b/kig/kig/kig_document.cc
new file mode 100644
index 00000000..884b41c5
--- /dev/null
+++ b/kig/kig/kig_document.cc
@@ -0,0 +1,200 @@
+// Copyright (C) 2004 Dominique Devriese <devriese@kde.org>
+
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+// 02110-1301, USA.
+
+#include "kig_document.h"
+
+#include "../objects/object_calcer.h"
+#include "../objects/object_holder.h"
+#include "../objects/point_imp.h"
+#include "../objects/polygon_imp.h"
+#include "../misc/coordinate_system.h"
+#include "../misc/rect.h"
+
+#include <assert.h>
+
+KigDocument::KigDocument( std::set<ObjectHolder*> objects, CoordinateSystem* coordsystem,
+ bool showgrid, bool showaxes, bool nv )
+ : mobjects( objects ), mcoordsystem( coordsystem ), mshowgrid( showgrid ),
+ mshowaxes( showaxes ), mnightvision( nv )
+{
+}
+
+const CoordinateSystem& KigDocument::coordinateSystem() const
+{
+ assert( mcoordsystem );
+ return *mcoordsystem;
+}
+
+const std::vector<ObjectHolder*> KigDocument::objects() const
+{
+ return std::vector<ObjectHolder*>( mobjects.begin(), mobjects.end() );
+}
+
+const std::set<ObjectHolder*>& KigDocument::objectsSet() const
+{
+ return mobjects;
+}
+
+void KigDocument::setCoordinateSystem( CoordinateSystem* s )
+{
+ delete switchCoordinateSystem( s );
+}
+
+CoordinateSystem* KigDocument::switchCoordinateSystem( CoordinateSystem* s )
+{
+ CoordinateSystem* ret = mcoordsystem;
+ mcoordsystem = s;
+ return ret;
+}
+
+std::vector<ObjectHolder*> KigDocument::whatAmIOn( const Coordinate& p, const KigWidget& w ) const
+{
+ std::vector<ObjectHolder*> ret;
+ std::vector<ObjectHolder*> curves;
+ std::vector<ObjectHolder*> fatobjects;
+ for ( std::set<ObjectHolder*>::const_iterator i = mobjects.begin();
+ i != mobjects.end(); ++i )
+ {
+ if(!(*i)->contains(p, w, mnightvision)) continue;
+ if ( (*i)->imp()->inherits( PointImp::stype() ) ) ret.push_back( *i );
+ else
+ if ( !(*i)->imp()->inherits( PolygonImp::stype() ) ) curves.push_back( *i );
+ else fatobjects.push_back( *i );
+ };
+ std::copy( curves.begin(), curves.end(), std::back_inserter( ret ) );
+ std::copy( fatobjects.begin(), fatobjects.end(), std::back_inserter( ret ) );
+ return ret;
+}
+
+std::vector<ObjectHolder*> KigDocument::whatIsInHere( const Rect& p, const KigWidget& w )
+{
+ std::vector<ObjectHolder*> ret;
+ std::vector<ObjectHolder*> nonpoints;
+ for ( std::set<ObjectHolder*>::const_iterator i = mobjects.begin();
+ i != mobjects.end(); ++i )
+ {
+ if(! (*i)->inRect( p, w ) ) continue;
+ if ( (*i)->imp()->inherits( PointImp::stype() ) ) ret.push_back( *i );
+ else nonpoints.push_back( *i );
+ };
+ std::copy( nonpoints.begin(), nonpoints.end(), std::back_inserter( ret ) );
+ return ret;
+}
+
+Rect KigDocument::suggestedRect() const
+{
+ bool rectInited = false;
+ Rect r(0.,0.,0.,0.);
+ for ( std::set<ObjectHolder*>::const_iterator i = mobjects.begin();
+ i != mobjects.end(); ++i )
+ {
+ if ( (*i)->shown() )
+ {
+ Rect cr = (*i)->imp()->surroundingRect();
+ if ( ! cr.valid() ) continue;
+ if( !rectInited )
+ {
+ r = cr;
+ rectInited = true;
+ }
+ else
+ r.eat( cr );
+ };
+ };
+
+ if ( ! rectInited )
+ return Rect( -5.5, -5.5, 11., 11. );
+ r.setContains( Coordinate( 0, 0 ) );
+ if( r.width() == 0 ) r.setWidth( 1 );
+ if( r.height() == 0 ) r.setHeight( 1 );
+ Coordinate center = r.center();
+ r *= 2;
+ r.setCenter(center);
+ return r;
+}
+
+void KigDocument::addObject( ObjectHolder* o )
+{
+ mobjects.insert( o );
+}
+
+void KigDocument::addObjects( const std::vector<ObjectHolder*>& os )
+{
+ for ( std::vector<ObjectHolder*>::const_iterator i = os.begin();
+ i != os.end(); ++i )
+ ( *i )->calc( *this );
+ std::copy( os.begin(), os.end(), std::inserter( mobjects, mobjects.begin() ) );
+}
+
+void KigDocument::delObject( ObjectHolder* o )
+{
+ mobjects.erase( o );
+}
+
+void KigDocument::delObjects( const std::vector<ObjectHolder*>& os )
+{
+ for ( std::vector<ObjectHolder*>::const_iterator i = os.begin();
+ i != os.end(); ++i )
+ mobjects.erase( *i );
+}
+
+KigDocument::KigDocument()
+ : mcoordsystem( new EuclideanCoords )
+{
+ mshowgrid = true;
+ mshowaxes = true;
+ mnightvision = false;
+}
+
+KigDocument::~KigDocument()
+{
+ typedef std::set<ObjectHolder*> s;
+ for ( s::iterator i = mobjects.begin(); i != mobjects.end(); ++i ) {
+ delete *i;
+ }
+ delete mcoordsystem;
+}
+
+void KigDocument::setGrid( bool showgrid )
+{
+ mshowgrid = showgrid;
+}
+
+const bool KigDocument::grid() const
+{
+ return mshowgrid;
+}
+
+void KigDocument::setAxes( bool showaxes )
+{
+ mshowaxes = showaxes;
+}
+
+void KigDocument::setNightVision( bool nv )
+{
+ mnightvision = nv;
+}
+
+const bool KigDocument::axes() const
+{
+ return mshowaxes;
+}
+
+const bool KigDocument::getNightVision() const
+{
+ return mnightvision;
+}
diff --git a/kig/kig/kig_document.h b/kig/kig/kig_document.h
new file mode 100644
index 00000000..6bcdb623
--- /dev/null
+++ b/kig/kig/kig_document.h
@@ -0,0 +1,137 @@
+// Copyright (C) 2004 Dominique Devriese <devriese@kde.org>
+
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+// 02110-1301, USA.
+
+#ifndef KIG_KIG_KIG_DOCUMENT_H
+#define KIG_KIG_KIG_DOCUMENT_H
+
+#include <set>
+#include <vector>
+
+class Coordinate;
+class CoordinateSystem;
+class KigWidget;
+class ObjectHolder;
+class Rect;
+
+/**
+ * KigDocument is the class holding the real data in a Kig document.
+ * It owns a set of Objects, and a CoordinateSystem, which comprise
+ * the entire content of a Kig document.
+ */
+class KigDocument {
+ /**
+ * Here we keep the objects in the document. These are only the
+ * objects that the user is aware of. Other objects exist as well,
+ * but there's no ObjectHolder for them, and they only exist because
+ * some other ObjectCalcer has them as its ancestor.
+ */
+ std::set<ObjectHolder*> mobjects;
+
+ /**
+ * The CoordinateSystem as the user sees it: this has little to do
+ * with the internal coordinates of the objects... It really serves
+ * to translate user coordinates from and to internal coordinates.
+ */
+ CoordinateSystem* mcoordsystem;
+ /**
+ * Whether to show the grid.
+ */
+ bool mshowgrid;
+ /**
+ * Whether to show the axes.
+ */
+ bool mshowaxes;
+ /**
+ * Whether to enable visibility of hidden objects.
+ */
+ bool mnightvision;
+public:
+ KigDocument();
+ KigDocument( std::set<ObjectHolder*> objects, CoordinateSystem* coordsystem,
+ bool showgrid = true, bool showaxes = true, bool nv = false );
+ ~KigDocument();
+
+ const CoordinateSystem& coordinateSystem() const;
+ const bool grid() const;
+ const bool axes() const;
+ const bool getNightVision() const;
+ /**
+ * Get a hold of the objects of this KigDocument.
+ */
+ const std::vector<ObjectHolder*> objects() const;
+ const std::set<ObjectHolder*>& objectsSet() const;
+
+ /**
+ * sets the coordinate system to \p s , and returns the old one..
+ */
+ CoordinateSystem* switchCoordinateSystem( CoordinateSystem* s );
+
+ /**
+ * sets the coordinate system to \p s , and deletes the old one..
+ */
+ void setCoordinateSystem( CoordinateSystem* s );
+
+ /**
+ * set to show/hide the grid.
+ */
+ void setGrid( bool showgrid );
+
+ /**
+ * set to show/hide the grid.
+ */
+ void setAxes( bool showaxes );
+
+ /**
+ * set to enable/disable night-vision (visibility of hidden objects)
+ */
+ void setNightVision( bool nv );
+
+ /**
+ * Return a vector of objects that contain the given point.
+ */
+ std::vector<ObjectHolder*> whatAmIOn( const Coordinate& p, const KigWidget& w ) const;
+
+ /**
+ * Return a vector of objects that are in the given Rect.
+ */
+ std::vector<ObjectHolder*> whatIsInHere( const Rect& p, const KigWidget& );
+
+ /**
+ * Return a rect containing most of the objects, which would be a
+ * fine suggestion to map to the widget...
+ */
+ Rect suggestedRect() const;
+
+ /**
+ * Add the objects \p o to the document.
+ */
+ void addObject( ObjectHolder* oObject );
+ /**
+ * Add the objects \p os to the document.
+ */
+ void addObjects( const std::vector<ObjectHolder*>& os);
+ /**
+ * Remove the object \p o from the document.
+ */
+ void delObject( ObjectHolder* o );
+ /**
+ * Remove the objects \p os from the document.
+ */
+ void delObjects( const std::vector<ObjectHolder*>& os );
+};
+
+#endif
diff --git a/kig/kig/kig_iface.cpp b/kig/kig/kig_iface.cpp
new file mode 100644
index 00000000..1f666a74
--- /dev/null
+++ b/kig/kig/kig_iface.cpp
@@ -0,0 +1,31 @@
+/**
+ This file is part of Kig, a KDE program for Interactive Geometry...
+ Copyright (C) 2002 Dominique Devriese <devriese@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ USA
+**/
+
+
+#include "kig_iface.h"
+
+KigIface::KigIface()
+ : DCOPObject("KigIface")
+{
+}
+
+KigIface::~KigIface()
+{
+}
diff --git a/kig/kig/kig_iface.h b/kig/kig/kig_iface.h
new file mode 100644
index 00000000..d3f74e19
--- /dev/null
+++ b/kig/kig/kig_iface.h
@@ -0,0 +1,37 @@
+/*
+ This file is part of Kig, a KDE program for Interactive Geometry...
+ Copyright (C) 2002 Dominique Devriese <devriese@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ USA
+*/
+
+
+#ifndef KIG_IFACE_H
+#define KIG_IFACE_H
+
+#include <dcopobject.h>
+
+class KigIface : virtual public DCOPObject
+{
+ K_DCOP
+public:
+ KigIface();
+ ~KigIface();
+k_dcop:
+ virtual void openURL(const QString& s) = 0;
+};
+
+#endif
diff --git a/kig/kig/kig_part.cpp b/kig/kig/kig_part.cpp
new file mode 100644
index 00000000..163f5429
--- /dev/null
+++ b/kig/kig/kig_part.cpp
@@ -0,0 +1,1041 @@
+/**
+ This file is part of Kig, a KDE program for Interactive Geometry...
+ Copyright (C) 2002 Dominique Devriese <devriese@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ USA
+**/
+
+#include "kig_part.h"
+#include "kig_part.moc"
+
+#include "aboutdata.h"
+#include "kig_commands.h"
+#include "kig_document.h"
+#include "kig_view.h"
+
+#include "../filters/exporter.h"
+#include "../filters/filter.h"
+#include "../misc/builtin_stuff.h"
+#include "../misc/calcpaths.h"
+#include "../misc/coordinate_system.h"
+#include "../misc/guiaction.h"
+#include "../misc/kigpainter.h"
+#include "../misc/lists.h"
+#include "../misc/object_constructor.h"
+#include "../misc/screeninfo.h"
+#include "../modes/normal.h"
+#include "../objects/object_drawer.h"
+#include "../objects/point_imp.h"
+
+#include <algorithm>
+#include <functional>
+
+#include <kaction.h>
+#include <kapplication.h>
+#include <kdebug.h>
+#include <kfiledialog.h>
+#include <kglobal.h>
+#include <kiconloader.h>
+#include <kinstance.h>
+#include <klocale.h>
+#include <kmainwindow.h>
+#include <kmessagebox.h>
+#include <kmimetype.h>
+#include <kprinter.h>
+#include <kstandarddirs.h>
+#include <kstdaction.h>
+#include <ktoolbar.h>
+#include <kparts/genericfactory.h>
+#include <kdeprint/kprintdialogpage.h>
+
+#include <qcheckbox.h>
+#include <qfile.h>
+#include <qlayout.h>
+#include <qpaintdevicemetrics.h>
+#include <qsizepolicy.h>
+#include <qtimer.h>
+#if QT_VERSION >= 0x030100
+#include <qeventloop.h>
+#endif
+
+using namespace std;
+
+static const QString typesFile = "macros.kigt";
+
+// export this library...
+typedef KParts::GenericFactory<KigPart> KigPartFactory;
+K_EXPORT_COMPONENT_FACTORY ( libkigpart, KigPartFactory )
+
+KAboutData* KigPart::createAboutData()
+{
+ return kigAboutData( "kig", I18N_NOOP( "KigPart" ) );
+}
+
+class SetCoordinateSystemAction
+ : public KSelectAction
+{
+ KigPart& md;
+public:
+ SetCoordinateSystemAction( KigPart& d, KActionCollection* parent );
+ void slotActivated( int index );
+};
+
+SetCoordinateSystemAction::SetCoordinateSystemAction(
+ KigPart& d, KActionCollection* parent )
+ : KSelectAction( i18n( "&Set Coordinate System" ), 0, parent, "settings_set_coordinate_system" ),
+ md( d )
+{
+ setItems( CoordinateSystemFactory::names() );
+ setCurrentItem( md.document().coordinateSystem().id() );
+}
+
+void SetCoordinateSystemAction::slotActivated( int index )
+{
+ CoordinateSystem* sys = CoordinateSystemFactory::build( index );
+ assert( sys );
+ md.history()->addCommand( KigCommand::changeCoordSystemCommand( md, sys ) );
+ setCurrentItem( index );
+}
+
+class KigPrintDialogPage
+ : public KPrintDialogPage
+{
+public:
+ KigPrintDialogPage( QWidget* parent = 0, const char* name = 0 );
+ ~KigPrintDialogPage();
+
+ void getOptions( QMap<QString,QString>& opts, bool );
+ void setOptions( const QMap<QString,QString>& opts );
+ bool isValid( QString& );
+
+private:
+ QCheckBox *showgrid;
+ QCheckBox *showaxes;
+};
+
+KigPrintDialogPage::KigPrintDialogPage( QWidget* parent, const char* name )
+ : KPrintDialogPage( parent, name )
+{
+ setTitle( i18n( "Kig Options" ) );
+
+ QVBoxLayout* vl = new QVBoxLayout( this, 0 , 11 );
+
+ showgrid = new QCheckBox( i18n( "Show grid" ), this );
+ vl->addWidget( showgrid );
+
+ showaxes = new QCheckBox( i18n( "Show axes" ), this );
+ vl->addWidget( showaxes );
+
+ vl->addItem( new QSpacerItem( 10, 10, QSizePolicy::Fixed, QSizePolicy::Expanding ) );
+}
+
+KigPrintDialogPage::~KigPrintDialogPage()
+{
+}
+
+void KigPrintDialogPage::getOptions( QMap< QString, QString >& opts, bool )
+{
+ opts[ "kde-kig-showgrid" ] = QString::number( showgrid->isChecked() );
+ opts[ "kde-kig-showaxes" ] = QString::number( showaxes->isChecked() );
+}
+
+void KigPrintDialogPage::setOptions( const QMap< QString, QString >& opts )
+{
+ QString tmp = opts[ "kde-kig-showgrid" ];
+ bool bt = ( tmp != "0" );
+ showgrid->setChecked( bt );
+ tmp = opts[ "kde-kig-showaxes" ];
+ bt = ( tmp != "0" );
+ showaxes->setChecked( bt );
+}
+
+bool KigPrintDialogPage::isValid( QString& )
+{
+ return true;
+}
+
+KigPart::KigPart( QWidget *parentWidget, const char *,
+ QObject *parent, const char *name,
+ const QStringList& )
+ : KParts::ReadWritePart( parent, name ),
+ mMode( 0 ), mdocument( new KigDocument() )
+{
+ // we need an instance
+ setInstance( KigPartFactory::instance() );
+
+ mMode = new NormalMode( *this );
+
+ // we need a widget, to actually show the document
+ m_widget = new KigView(this, false, parentWidget, "kig_view");
+ // notify the part that this is our internal widget
+ setWidget( m_widget );
+
+ // create our actions...
+ setupActions();
+
+ // set our XML-UI resource file
+ setXMLFile("kigpartui.rc");
+
+ // our types...
+ setupTypes();
+
+ // construct our command history
+ mhistory = new KCommandHistory(actionCollection());
+ mhistory->documentSaved();
+ connect( mhistory, SIGNAL( documentRestored() ), this, SLOT( setUnmodified() ) );
+
+ // we are read-write by default
+ setReadWrite(true);
+
+ setModified (false);
+
+ GUIActionList::instance()->regDoc( this );
+}
+
+void KigPart::setupActions()
+{
+ // save actions..
+ (void) KStdAction::saveAs(this, SLOT(fileSaveAs()), actionCollection());
+ (void) KStdAction::save(this, SLOT(fileSave()), actionCollection());
+
+ // print actions
+ (void) KStdAction::print( this, SLOT( filePrint() ), actionCollection() );
+ (void) KStdAction::printPreview( this, SLOT( filePrintPreview() ), actionCollection() );
+
+ // selection actions
+ aSelectAll = KStdAction::selectAll(
+ this, SLOT( slotSelectAll() ), actionCollection() );
+ aDeselectAll = KStdAction::deselect(
+ this, SLOT( slotDeselectAll() ), actionCollection() );
+ aInvertSelection = new KAction(
+ i18n( "Invert Selection" ), "", 0, this,
+ SLOT( slotInvertSelection() ), actionCollection(),
+ "edit_invert_selection" );
+
+ // we need icons...
+ KIconLoader* l = instance()->iconLoader();
+ QPixmap tmp;
+
+ aDeleteObjects = new KAction(
+ i18n("&Delete Objects"), "editdelete", Key_Delete, this,
+ SLOT(deleteObjects()), actionCollection(), "delete_objects");
+ aDeleteObjects->setToolTip(i18n("Delete the selected objects"));
+
+ aCancelConstruction = new KAction(
+ i18n("Cancel Construction"), "stop", Key_Escape, this,
+ SLOT(cancelConstruction()), actionCollection(), "cancel_construction");
+ aCancelConstruction->setToolTip(
+ i18n("Cancel the construction of the object being constructed"));
+ aCancelConstruction->setEnabled(false);
+
+ aShowHidden = new KAction(
+ i18n("U&nhide All"), 0, this, SLOT( showHidden() ),
+ actionCollection(), "edit_unhide_all");
+ aShowHidden->setToolTip(i18n("Show all hidden objects"));
+ aShowHidden->setEnabled( true );
+
+ aNewMacro = new KAction(
+ i18n("&New Macro..."), "gear", 0, this, SLOT(newMacro()),
+ actionCollection(), "macro_action");
+ aNewMacro->setToolTip(i18n("Define a new macro"));
+
+ aConfigureTypes = new KAction(
+ i18n("Manage &Types..."), 0, this, SLOT(editTypes()),
+ actionCollection(), "types_edit");
+ aConfigureTypes->setToolTip(i18n("Manage macro types."));
+
+ KigExportManager::instance()->addMenuAction( this, m_widget->realWidget(),
+ actionCollection() );
+
+ KAction* a = KStdAction::zoomIn( m_widget, SLOT( slotZoomIn() ),
+ actionCollection() );
+ a->setToolTip( i18n( "Zoom in on the document" ) );
+ a->setWhatsThis( i18n( "Zoom in on the document" ) );
+
+ a = KStdAction::zoomOut( m_widget, SLOT( slotZoomOut() ),
+ actionCollection() );
+ a->setToolTip( i18n( "Zoom out of the document" ) );
+ a->setWhatsThis( i18n( "Zoom out of the document" ) );
+
+ a = KStdAction::fitToPage( m_widget, SLOT( slotRecenterScreen() ),
+ actionCollection() );
+ // grr.. why isn't there an icon for this..
+ a->setIconSet( QIconSet( l->loadIcon( "view_fit_to_page", KIcon::Toolbar ) ) );
+ a->setToolTip( i18n( "Recenter the screen on the document" ) );
+ a->setWhatsThis( i18n( "Recenter the screen on the document" ) );
+
+#ifdef KDE_IS_VERSION
+#if KDE_IS_VERSION(3,1,90)
+#define KIG_PART_CPP_STD_FULLSCREEN_ACTION
+#endif
+#endif
+#ifdef KIG_PART_CPP_STD_FULLSCREEN_ACTION
+ a = KStdAction::fullScreen( m_widget, SLOT( toggleFullScreen() ), actionCollection(), (QWidget*)(widget()->parent()),"fullscreen" );
+#else
+ tmp = l->loadIcon( "window_fullscreen", KIcon::Toolbar );
+ a = new KAction(
+ i18n( "Full Screen" ), tmp, CTRL+SHIFT+Key_F,
+ m_widget, SLOT( toggleFullScreen() ),
+ actionCollection(), "fullscreen" );
+#endif
+ a->setToolTip( i18n( "View this document full-screen." ) );
+ a->setWhatsThis( i18n( "View this document full-screen." ) );
+
+ // TODO: an icon for this..
+ a = new KAction(
+ i18n( "&Select Shown Area" ), "viewmagfit", 0, m_widget, SLOT( zoomRect() ),
+ actionCollection(), "view_select_shown_rect" );
+ a->setToolTip( i18n( "Select the area that you want to be shown in the window." ) );
+ a->setWhatsThis( i18n( "Select the area that you want to be shown in the window." ) );
+
+ a = new KAction(
+ i18n( "S&elect Zoom Area" ), "viewmag", 0, m_widget, SLOT( zoomArea() ),
+ actionCollection(), "view_zoom_area" );
+// a->setToolTip( i18n( "Select the area that you want to be shown in the window." ) );
+// a->setWhatsThis( i18n( "Select the area that you want to be shown in the window." ) );
+
+ aToggleGrid = new KToggleAction(
+ i18n( "Show &Grid" ), 0, this, SLOT( toggleGrid() ),
+ actionCollection(), "settings_show_grid" );
+ aToggleGrid->setToolTip( i18n( "Show or hide the grid." ) );
+ aToggleGrid->setChecked( true );
+
+ aToggleAxes = new KToggleAction(
+ i18n( "Show &Axes" ), 0, this, SLOT( toggleAxes() ),
+ actionCollection(), "settings_show_axes" );
+ aToggleAxes->setToolTip( i18n( "Show or hide the axes." ) );
+ aToggleAxes->setChecked( true );
+
+ aToggleNightVision = new KToggleAction(
+ i18n( "Wear Infrared Glasses" ), 0, this, SLOT( toggleNightVision() ),
+ actionCollection(), "settings_toggle_nightvision" );
+ aToggleNightVision->setToolTip( i18n( "Enable/Disable hidden objects visibility." ) );
+ aToggleNightVision->setChecked( false );
+
+ // select coordinate system KActionMenu..
+ aCoordSystem = new SetCoordinateSystemAction( *this, actionCollection() );
+}
+
+void KigPart::setupTypes()
+{
+ setupBuiltinStuff();
+ setupBuiltinMacros();
+ setupMacroTypes();
+ GUIActionList& l = *GUIActionList::instance();
+ typedef GUIActionList::avectype::const_iterator iter;
+ for ( iter i = l.actions().begin(); i != l.actions().end(); ++i )
+ {
+ KigGUIAction* ret = new KigGUIAction( *i, *this, actionCollection() );
+ aActions.push_back( ret );
+ ret->plug( this );
+ };
+}
+
+KigPart::~KigPart()
+{
+ GUIActionList::instance()->unregDoc( this );
+
+ // save our types...
+ saveTypes();
+
+ // objects get deleted automatically, when mobjsref gets
+ // destructed..
+
+ delete_all( aActions.begin(), aActions.end() );
+ aActions.clear();
+
+ // cleanup
+ delete mMode;
+ delete mhistory;
+
+ delete mdocument;
+}
+
+bool KigPart::openFile()
+{
+ QFileInfo fileinfo( m_file );
+ if ( ! fileinfo.exists() )
+ {
+ KMessageBox::sorry( widget(),
+ i18n( "The file \"%1\" you tried to open does not exist. "
+ "Please verify that you entered the correct path." ).arg( m_file ),
+ i18n( "File Not Found" ) );
+ return false;
+ };
+
+ // m_file is always local, so we can use findByPath instead of
+ // findByURL...
+ KMimeType::Ptr mimeType = KMimeType::findByPath ( m_file );
+ kdDebug() << k_funcinfo << "mimetype: " << mimeType->name() << endl;
+ KigFilter* filter = KigFilters::instance()->find( mimeType->name() );
+ if ( !filter )
+ {
+ // we don't support this mime type...
+ KMessageBox::sorry
+ (
+ widget(),
+ i18n( "You tried to open a document of type \"%1\"; unfortunately, "
+ "Kig does not support this format. If you think the format in "
+ "question would be worth implementing support for, you can "
+ "always ask us nicely on mailto:toscano.pino@tiscali.it "
+ "or do the work yourself and send me a patch."
+ ).arg(mimeType->name()),
+ i18n( "Format Not Supported" )
+ );
+ return false;
+ };
+
+ KigDocument* newdoc = filter->load (m_file);
+ if ( !newdoc )
+ {
+ closeURL();
+ m_url = KURL();
+ return false;
+ }
+ delete mdocument;
+ mdocument = newdoc;
+ coordSystemChanged( mdocument->coordinateSystem().id() );
+ aToggleGrid->setChecked( mdocument->grid() );
+ aToggleAxes->setChecked( mdocument->axes() );
+ aToggleNightVision->setChecked( mdocument->getNightVision() );
+
+ setModified(false);
+ mhistory->clear();
+
+ std::vector<ObjectCalcer*> tmp = calcPath( getAllParents( getAllCalcers( document().objects() ) ) );
+ for ( std::vector<ObjectCalcer*>::iterator i = tmp.begin(); i != tmp.end(); ++i )
+ ( *i )->calc( document() );
+ emit recenterScreen();
+
+ redrawScreen();
+
+ return true;
+}
+
+bool KigPart::saveFile()
+{
+ if ( m_file.isEmpty() || m_bTemp ) return internalSaveAs();
+ // mimetype:
+ KMimeType::Ptr mimeType = KMimeType::findByPath ( m_file );
+ if ( mimeType->name() != "application/x-kig" )
+ {
+ // we don't support this mime type...
+ if( KMessageBox::warningYesNo( widget(),
+ i18n( "Kig does not support saving to any other file format than "
+ "its own. Save to Kig's format instead?" ),
+ i18n( "Format Not Supported" ), i18n("Save Kig Format"), KStdGuiItem::cancel() ) == KMessageBox::No )
+ return false;
+ internalSaveAs();
+ };
+
+ if ( KigFilters::instance()->save( document(), m_file ) )
+ {
+ setModified ( false );
+ mhistory->documentSaved();
+ return true;
+ }
+ return false;
+}
+
+void KigPart::addObject(ObjectHolder* o)
+{
+ mhistory->addCommand( KigCommand::addCommand( *this, o ) );
+}
+
+void KigPart::addObjects( const std::vector<ObjectHolder*>& os )
+{
+ mhistory->addCommand( KigCommand::addCommand( *this, os ) );
+}
+
+void KigPart::_addObject( ObjectHolder* o )
+{
+ document().addObject( o );
+ setModified(true);
+}
+
+void KigPart::delObject( ObjectHolder* o )
+{
+ // we delete all children and their children etc. too...
+ std::vector<ObjectHolder*> os;
+ os.push_back( o );
+ delObjects( os );
+}
+
+void KigPart::_delObjects( const std::vector<ObjectHolder*>& o )
+{
+ document().delObjects( o );
+ setModified( true );
+}
+
+void KigPart::_delObject(ObjectHolder* o)
+{
+ document().delObject( o );
+ setModified(true);
+}
+
+void KigPart::setMode( KigMode* m )
+{
+ mMode = m;
+ m->enableActions();
+ redrawScreen();
+}
+
+void KigPart::_addObjects( const std::vector<ObjectHolder*>& os )
+{
+ document().addObjects( os );
+ setModified( true );
+}
+
+void KigPart::deleteObjects()
+{
+ mode()->deleteObjects();
+}
+
+void KigPart::cancelConstruction()
+{
+ mode()->cancelConstruction();
+}
+
+void KigPart::showHidden()
+{
+ mode()->showHidden();
+}
+
+void KigPart::newMacro()
+{
+ mode()->newMacro();
+}
+
+void KigPart::editTypes()
+{
+ mode()->editTypes();
+}
+
+void KigPart::setUnmodified()
+{
+ setModified( false );
+}
+
+KCommandHistory* KigPart::history()
+{
+ return mhistory;
+}
+
+void KigPart::delObjects( const std::vector<ObjectHolder*>& os )
+{
+ if ( os.size() < 1 ) return;
+ std::set<ObjectHolder*> delobjs;
+
+ std::set<ObjectCalcer*> delcalcers = getAllChildren( getAllCalcers( os ) );
+ std::map<ObjectCalcer*, ObjectHolder*> holdermap;
+
+ std::set<ObjectHolder*> curobjs = document().objectsSet();
+
+ for ( std::set<ObjectHolder*>::iterator i = curobjs.begin();
+ i != curobjs.end(); ++i )
+ holdermap[( *i )->calcer()] = *i;
+
+ for ( std::set<ObjectCalcer*>::iterator i = delcalcers.begin();
+ i != delcalcers.end(); ++i )
+ {
+ std::map<ObjectCalcer*, ObjectHolder*>::iterator j = holdermap.find( *i );
+ if ( j != holdermap.end() )
+ delobjs.insert( j->second );
+ }
+
+ assert( delobjs.size() >= os.size() );
+
+ std::vector<ObjectHolder*> delobjsvect( delobjs.begin(), delobjs.end() );
+ mhistory->addCommand( KigCommand::removeCommand( *this, delobjsvect ) );
+}
+
+void KigPart::enableConstructActions( bool enabled )
+{
+ for_each( aActions.begin(), aActions.end(),
+ bind2nd( mem_fun( &KAction::setEnabled ),
+ enabled ) );
+}
+
+void KigPart::unplugActionLists()
+{
+ unplugActionList( "user_conic_types" );
+ unplugActionList( "user_segment_types" );
+ unplugActionList( "user_point_types" );
+ unplugActionList( "user_circle_types" );
+ unplugActionList( "user_line_types" );
+ unplugActionList( "user_other_types" );
+ unplugActionList( "user_types" );
+}
+
+void KigPart::plugActionLists()
+{
+ plugActionList( "user_conic_types", aMNewConic );
+ plugActionList( "user_segment_types", aMNewSegment );
+ plugActionList( "user_point_types", aMNewPoint );
+ plugActionList( "user_circle_types", aMNewCircle );
+ plugActionList( "user_line_types", aMNewLine );
+ plugActionList( "user_other_types", aMNewOther );
+ plugActionList( "user_types", aMNewAll );
+}
+
+void KigPart::emitStatusBarText( const QString& text )
+{
+ emit setStatusBarText( text );
+}
+
+void KigPart::fileSaveAs()
+{
+ internalSaveAs();
+}
+
+void KigPart::fileSave()
+{
+ save();
+}
+
+bool KigPart::internalSaveAs()
+{
+ // this slot is connected to the KStdAction::saveAs action...
+ QString formats = i18n( "*.kig|Kig Documents (*.kig)\n"
+ "*.kigz|Compressed Kig Documents (*.kigz)" );
+
+ // formats += "\n";
+ // formats += KImageIO::pattern( KImageIO::Writing );
+
+ QString file_name = KFileDialog::getSaveFileName(":document", formats );
+ if (file_name.isEmpty()) return false;
+ else if ( QFileInfo( file_name ).exists() )
+ {
+ int ret = KMessageBox::warningContinueCancel( m_widget,
+ i18n( "The file \"%1\" already exists. Do you wish to overwrite it?" )
+ .arg( file_name ), i18n( "Overwrite File?" ), i18n("Overwrite") );
+ if ( ret != KMessageBox::Continue )
+ {
+ return false;
+ }
+ }
+ saveAs(KURL::fromPathOrURL( file_name ));
+ return true;
+}
+
+void KigPart::runMode( KigMode* m )
+{
+ KigMode* prev = mMode;
+
+ setMode( m );
+
+#if QT_VERSION >= 0x030100
+ (void) kapp->eventLoop()->enterLoop();
+#else
+ (void) kapp->enter_loop();
+#endif
+
+ setMode( prev );
+ redrawScreen();
+}
+
+void KigPart::doneMode( KigMode* d )
+{
+ assert( d == mMode );
+ // pretend to use this var..
+ (void)d;
+#if QT_VERSION >= 0x030100
+ kapp->eventLoop()->exitLoop();
+#else
+ kapp->exit_loop();
+#endif
+}
+
+void KigPart::actionRemoved( GUIAction* a, GUIUpdateToken& t )
+{
+ KigGUIAction* rem = 0;
+ for ( std::vector<KigGUIAction*>::iterator i = aActions.begin(); i != aActions.end(); ++i )
+ {
+ if ( (*i)->guiAction() == a )
+ {
+ rem = *i;
+ aActions.erase( i );
+ break;
+ }
+ };
+ assert( rem );
+ aMNewSegment.remove( rem );
+ aMNewConic.remove( rem );
+ aMNewPoint.remove( rem );
+ aMNewCircle.remove( rem );
+ aMNewLine.remove( rem );
+ aMNewOther.remove( rem );
+ aMNewAll.remove( rem );
+ t.push_back( rem );
+}
+
+void KigPart::actionAdded( GUIAction* a, GUIUpdateToken& )
+{
+ KigGUIAction* ret = new KigGUIAction( a, *this, actionCollection() );
+ aActions.push_back( ret );
+ ret->plug( this );
+}
+
+void KigPart::endGUIActionUpdate( GUIUpdateToken& t )
+{
+ unplugActionLists();
+ plugActionLists();
+ delete_all( t.begin(), t.end() );
+ t.clear();
+}
+
+KigPart::GUIUpdateToken KigPart::startGUIActionUpdate()
+{
+ return GUIUpdateToken();
+}
+
+void KigPart::setupMacroTypes()
+{
+ static bool alreadysetup = false;
+ if ( ! alreadysetup )
+ {
+ alreadysetup = true;
+
+ // the user's saved macro types:
+ QStringList dataFiles =
+ KGlobal::dirs()->findAllResources("appdata", "kig-types/*.kigt",
+ true, false );
+ std::vector<Macro*> macros;
+ for ( QStringList::iterator file = dataFiles.begin();
+ file != dataFiles.end(); ++file )
+ {
+ std::vector<Macro*> nmacros;
+ bool ok = MacroList::instance()->load( *file, nmacros, *this );
+ if ( ! ok ) continue;
+ copy( nmacros.begin(), nmacros.end(), back_inserter( macros ) );
+ }
+ MacroList::instance()->add( macros );
+ };
+ // hack: we need to plug the action lists _after_ the gui is
+ // built.. i can't find a better solution than this...
+ QTimer::singleShot( 0, this, SLOT( plugActionLists() ) );
+}
+
+void KigPart::setupBuiltinMacros()
+{
+ static bool alreadysetup = false;
+ if ( ! alreadysetup )
+ {
+ alreadysetup = true;
+ // builtin macro types ( we try to make the user think these are
+ // normal types )..
+ QStringList builtinfiles =
+ KGlobal::dirs()->findAllResources( "appdata", "builtin-macros/*.kigt", true, false );
+ for ( QStringList::iterator file = builtinfiles.begin();
+ file != builtinfiles.end(); ++file )
+ {
+ std::vector<Macro*> macros;
+ bool ok = MacroList::instance()->load( *file, macros, *this );
+ if ( ! ok ) continue;
+ for ( uint i = 0; i < macros.size(); ++i )
+ {
+ ObjectConstructorList* ctors = ObjectConstructorList::instance();
+ GUIActionList* actions = GUIActionList::instance();
+ Macro* macro = macros[i];
+ macro->ctor->setBuiltin( true );
+ ctors->add( macro->ctor );
+ actions->add( macro->action );
+ macro->ctor = 0;
+ macro->action = 0;
+ delete macro;
+ };
+ };
+ };
+}
+
+void KigPart::addWidget( KigWidget* v )
+{
+ mwidgets.push_back( v );
+}
+
+void KigPart::delWidget( KigWidget* v )
+{
+ mwidgets.erase( std::remove( mwidgets.begin(), mwidgets.end(), v ), mwidgets.end() );
+}
+
+void KigPart::filePrintPreview()
+{
+ KPrinter printer;
+ printer.setPreviewOnly( true );
+ doPrint( printer );
+}
+
+void KigPart::filePrint()
+{
+ KPrinter printer;
+ KigPrintDialogPage* kp = new KigPrintDialogPage();
+ printer.addDialogPage( kp );
+ printer.setFullPage( true );
+ printer.setOption( "kde-kig-showgrid", QString::number( document().grid() ) );
+ printer.setOption( "kde-kig-showaxes", QString::number( document().axes() ) );
+ printer.setPageSelection( KPrinter::ApplicationSide );
+ if ( printer.setup( m_widget, i18n("Print Geometry") ) )
+ {
+ doPrint( printer );
+ };
+}
+
+void KigPart::doPrint( KPrinter& printer )
+{
+ QPaintDeviceMetrics metrics( &printer );
+ Rect rect = document().suggestedRect();
+ QRect qrect( 0, 0, metrics.width(), metrics.height() );
+ if ( rect.width() * qrect.height() > rect.height() * qrect.width() )
+ {
+ // qrect is too high..
+ int nh = static_cast<int>( qrect.width() * rect.height() / rect.width() );
+ int rest = qrect.height() - nh;
+ qrect.setTop( qrect.top() - rest / 2 );
+ qrect.setTop( rest / 2 );
+ }
+ else
+ {
+ // qrect is too wide..
+ int nw = static_cast<int>( qrect.height() * rect.width() / rect.height() );
+ int rest = qrect.width() - nw;
+ qrect.setLeft( rest / 2 );
+ qrect.setRight( qrect.right() - rest / 2 );
+ };
+ ScreenInfo si( rect, qrect );
+ KigPainter painter( si, &printer, document() );
+ painter.setWholeWinOverlay();
+ bool sg = true;
+ bool sa = true;
+ if ( !printer.previewOnly() )
+ {
+ sg = ( printer.option( "kde-kig-showgrid" ) != "0" );
+ sa = ( printer.option( "kde-kig-showaxes" ) != "0" );
+ }
+ else
+ {
+ sg = document().grid();
+ sg = document().axes();
+ }
+ painter.drawGrid( document().coordinateSystem(), sg, sa );
+ painter.drawObjects( document().objects(), false );
+}
+
+void KigPart::slotSelectAll()
+{
+ mMode->selectAll();
+}
+
+void KigPart::slotDeselectAll()
+{
+ mMode->deselectAll();
+}
+
+void KigPart::slotInvertSelection()
+{
+ mMode->invertSelection();
+}
+
+void KigPart::hideObjects( const std::vector<ObjectHolder*>& inos )
+{
+ std::vector<ObjectHolder*> os;
+ for (std::vector<ObjectHolder*>::const_iterator i = inos.begin(); i != inos.end(); ++i )
+ {
+ if ( (*i)->shown() )
+ os.push_back( *i );
+ };
+ KigCommand* kc = 0;
+ if ( os.size() == 0 ) return;
+ else if ( os.size() == 1 )
+ kc = new KigCommand( *this, os[0]->imp()->type()->hideAStatement() );
+ else kc = new KigCommand( *this, i18n( "Hide %n Object", "Hide %n Objects", os.size() ) );
+ for ( std::vector<ObjectHolder*>::iterator i = os.begin();
+ i != os.end(); ++i )
+ kc->addTask( new ChangeObjectDrawerTask( *i, ( *i )->drawer()->getCopyShown( false ) ) );
+ mhistory->addCommand( kc );
+}
+
+void KigPart::showObjects( const std::vector<ObjectHolder*>& inos )
+{
+ std::vector<ObjectHolder*> os;
+ for (std::vector<ObjectHolder*>::const_iterator i = inos.begin(); i != inos.end(); ++i )
+ {
+ if ( !(*i)->shown() )
+ os.push_back( *i );
+ };
+ KigCommand* kc = 0;
+ if ( os.size() == 0 ) return;
+ else if ( os.size() == 1 )
+ kc = new KigCommand( *this, os[0]->imp()->type()->showAStatement() );
+ else kc = new KigCommand( *this, i18n( "Show %n Object", "Show %n Objects", os.size() ) );
+ for ( std::vector<ObjectHolder*>::iterator i = os.begin();
+ i != os.end(); ++i )
+ kc->addTask( new ChangeObjectDrawerTask( *i, ( *i )->drawer()->getCopyShown( true ) ) );
+ mhistory->addCommand( kc );
+}
+
+void KigPart::redrawScreen( KigWidget* w )
+{
+ mode()->redrawScreen( w );
+}
+
+void KigPart::redrawScreen()
+{
+ for ( std::vector<KigWidget*>::iterator i = mwidgets.begin();
+ i != mwidgets.end(); ++i )
+ {
+ mode()->redrawScreen( *i );
+ }
+}
+
+const KigDocument& KigPart::document() const
+{
+ return *mdocument;
+}
+
+KigDocument& KigPart::document()
+{
+ return *mdocument;
+}
+
+extern "C" int convertToNative( const KURL& url, const QCString& outfile )
+{
+ kdDebug() << "converting " << url.prettyURL() << " to " << outfile << endl;
+
+ if ( ! url.isLocalFile() )
+ {
+ // TODO
+ kdError() << "--convert-to-native only supports local files for now." << endl;
+ return -1;
+ }
+
+ QString file = url.path();
+
+ QFileInfo fileinfo( file );
+ if ( ! fileinfo.exists() )
+ {
+ kdError() << "The file \"" << file << "\" does not exist" << endl;
+ return -1;
+ };
+
+ KMimeType::Ptr mimeType = KMimeType::findByPath ( file );
+ kdDebug() << k_funcinfo << "mimetype: " << mimeType->name() << endl;
+ KigFilter* filter = KigFilters::instance()->find( mimeType->name() );
+ if ( !filter )
+ {
+ kdError() << "The file \"" << file << "\" is of a filetype not currently supported by Kig." << endl;
+ return -1;
+ };
+
+ KigDocument* doc = filter->load (file);
+ if ( !doc )
+ {
+ kdError() << "Parse error in file \"" << file << "\"." << endl;
+ return -1;
+ }
+
+ std::vector<ObjectCalcer*> tmp = calcPath( getAllParents( getAllCalcers( doc->objects() ) ) );
+ for ( std::vector<ObjectCalcer*>::iterator i = tmp.begin(); i != tmp.end(); ++i )
+ ( *i )->calc( *doc );
+ for ( std::vector<ObjectCalcer*>::iterator i = tmp.begin(); i != tmp.end(); ++i )
+ ( *i )->calc( *doc );
+
+ QString out = ( outfile == "-" ) ? QString::null : outfile;
+ bool success = KigFilters::instance()->save( *doc, out );
+ if ( !success )
+ {
+ kdError() << "something went wrong while saving" << endl;
+ return -1;
+ }
+
+ delete doc;
+
+ return 0;
+}
+
+void KigPart::toggleGrid()
+{
+ bool toshow = !mdocument->grid();
+ aToggleGrid->setChecked( toshow );
+ mdocument->setGrid( toshow );
+
+ redrawScreen();
+}
+
+void KigPart::toggleAxes()
+{
+ bool toshow = !mdocument->axes();
+ aToggleAxes->setChecked( toshow );
+ mdocument->setAxes( toshow );
+
+ redrawScreen();
+}
+
+void KigPart::toggleNightVision()
+{
+ bool nv = !mdocument->getNightVision();
+ aToggleNightVision->setChecked( nv );
+ mdocument->setNightVision( nv );
+
+ redrawScreen();
+}
+
+void KigPart::coordSystemChanged( int id )
+{
+ aCoordSystem->setCurrentItem( id );
+}
+
+void KigPart::saveTypes()
+{
+ QString typesDir = KGlobal::dirs()->saveLocation( "appdata", "kig-types" );
+ if ( typesDir[ typesDir.length() - 1 ] != '/' )
+ typesDir += '/';
+ QString typesFileWithPath = typesDir + typesFile;
+
+ // removing existant types file
+ if ( QFile::exists( typesFileWithPath ) )
+ QFile::remove( typesFileWithPath );
+
+ MacroList* macrolist = MacroList::instance();
+ macrolist->save( macrolist->macros(), typesFileWithPath );
+}
+
+void KigPart::loadTypes()
+{
+ QString typesDir = KGlobal::dirs()->saveLocation( "appdata", "kig-types" );
+ if ( typesDir[ typesDir.length() - 1 ] != '/' )
+ typesDir += '/';
+ QString typesFileWithPath = typesDir + typesFile;
+
+ if ( QFile::exists( typesFileWithPath ) )
+ {
+ std::vector<Macro*> macros;
+ MacroList::instance()->load( typesFileWithPath, macros, *this );
+ MacroList::instance()->add( macros );
+ }
+}
+
+void KigPart::deleteTypes()
+{
+ unplugActionLists();
+ typedef MacroList::vectype vec;
+ MacroList* macrolist = MacroList::instance();
+ const vec& macros = macrolist->macros();
+ for ( vec::const_reverse_iterator i = macros.rbegin(); i != macros.rend(); ++i )
+ {
+ macrolist->remove( *i );
+ }
+ plugActionLists();
+}
diff --git a/kig/kig/kig_part.desktop b/kig/kig/kig_part.desktop
new file mode 100644
index 00000000..cffd6e3d
--- /dev/null
+++ b/kig/kig/kig_part.desktop
@@ -0,0 +1,16 @@
+[Desktop Entry]
+Name=KigPart
+Name[ar]=جزء كيج
+Name[bn]=কিগপার্ট
+Name[et]=Kigi komponent
+Name[hi]=के-इग-पार्ट
+Name[ne]=किग पार्ट
+Name[sv]=Kigdel
+Name[ta]=கிக்பகுதி
+Name[ven]=TshipidatshaKig
+Name[zh_CN]=Kig 组件
+MimeType=application/x-kig;application/x-kgeo;
+ServiceTypes=KParts/ReadOnlyPart,KParts/ReadWritePart
+X-KDE-Library=libkigpart
+Type=Service
+Icon=kig
diff --git a/kig/kig/kig_part.h b/kig/kig/kig_part.h
new file mode 100644
index 00000000..2084d0a9
--- /dev/null
+++ b/kig/kig/kig_part.h
@@ -0,0 +1,257 @@
+/**
+ This file is part of Kig, a KDE program for Interactive Geometry...
+ Copyright (C) 2002 Dominique Devriese <devriese@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ USA
+**/
+
+
+#ifndef KIGPART_H
+#define KIGPART_H
+
+#include <qptrlist.h>
+
+#include <kparts/part.h>
+
+#include "../objects/common.h"
+
+class KAboutData;
+class KActionMenu;
+class KCommandHistory;
+class KPrinter;
+class KSelectAction;
+class KToolBar;
+class KToggleAction;
+class KURL;
+class QWidget;
+
+class Coordinate;
+class CoordinateSystem;
+class GUIAction;
+class KigGUIAction;
+class KigMode;
+class KigObjectsPopup;
+class KigView;
+class MacroWizardImpl;
+class ObjectHolder;
+class Rect;
+class ScreenInfo;
+
+/**
+ * This is a "Part". It that does all the real work in a KPart
+ * application.
+ * Briefly, it holds the data of the document, and acts as an
+ * interface to shells
+ *
+ * @short Main Part
+ */
+class KigPart : public KParts::ReadWritePart
+{
+ Q_OBJECT
+public:
+ /**
+ * Default constructor
+ */
+ KigPart( QWidget* parentWidget, const char* widgetName,
+ QObject* parent = 0, const char* name = 0,
+ const QStringList& = QStringList()
+ );
+
+ /**
+ * Destructor
+ */
+ virtual ~KigPart();
+
+/*********************** KPart interface *************************/
+
+protected:
+ /**
+ * load our internal document from m_file
+ */
+ virtual bool openFile();
+
+ /**
+ * save our internal document to m_file
+ */
+ virtual bool saveFile();
+
+public:
+ void emitStatusBarText( const QString& text );
+ void redrawScreen();
+ void redrawScreen( KigWidget* w );
+
+public slots:
+ void fileSaveAs();
+ void fileSave();
+
+ void filePrint();
+ void filePrintPreview();
+
+ void slotSelectAll();
+ void slotDeselectAll();
+ void slotInvertSelection();
+
+ void unplugActionLists();
+ void plugActionLists();
+
+ void deleteObjects();
+ void cancelConstruction();
+ void showHidden();
+ void newMacro();
+ void editTypes();
+
+ void toggleGrid();
+ void toggleAxes();
+ void toggleNightVision();
+
+ /**
+ * equivalent to setModified( false ); ( did i mention i don't like
+ * signals/slots for being this inflexible...
+ * this is connected to mhistory->documentRestored();
+ */
+ void setUnmodified();
+
+ /****************** cooperation with stuff ******************/
+public:
+ void addWidget( KigWidget* );
+ void delWidget( KigWidget* );
+
+ KigMode* mode() const { return mMode; }
+ void setMode( KigMode* );
+ void runMode( KigMode* );
+ void doneMode( KigMode* );
+
+ void coordSystemChanged( int );
+
+signals: // these signals are for telling KigView it should do something...
+ /**
+ * emitted when we want to suggest a new size for the view
+ * ( basically after loading a file, and on startup... )
+ */
+ void recenterScreen();
+
+/************** working with our internal document **********/
+public:
+ // guess what these do...
+ // actually, they only add a command object to the history, the real
+ // work is done in _addObject() and _delObject()
+ void addObject(ObjectHolder* inObject);
+ void addObjects( const std::vector<ObjectHolder*>& os );
+ void delObject(ObjectHolder* inObject);
+ void delObjects( const std::vector<ObjectHolder*>& os );
+ void hideObjects( const std::vector<ObjectHolder*>& os );
+ void showObjects( const std::vector<ObjectHolder*>& os );
+
+ void _addObject( ObjectHolder* inObject );
+ void _addObjects( const std::vector<ObjectHolder*>& o);
+ void _delObject( ObjectHolder* inObject );
+ void _delObjects( const std::vector<ObjectHolder*>& o );
+
+/************* internal stuff *************/
+protected:
+ bool internalSaveAs();
+
+public:
+ static KAboutData* createAboutData();
+protected:
+ void setupActions();
+ void setupTypes();
+ void setupBuiltinMacros();
+ void setupMacroTypes();
+
+protected:
+ KigMode* mMode;
+ KSelectAction* aCoordSystem;
+
+ /**
+ * the command history
+ */
+ KCommandHistory* mhistory;
+
+public:
+ // actions: this is an annoying case, didn't really fit into my
+ // model with KigModes.. This is how it works now:
+ // the actions are owned by the Part, because we need them on
+ // constructing the GUI ( actions appearing when you switch modes
+ // would not be nice, imho ). On setting the KigPart mode, we
+ // connect the actions to the current mode, and disconnect them from
+ // the previous mode. Enabling/disabling is done at the same time,
+ // of course..
+ // some MenuActions..
+ QPtrList<KAction> aMNewSegment;
+ QPtrList<KAction> aMNewPoint;
+ QPtrList<KAction> aMNewCircle;
+ QPtrList<KAction> aMNewLine;
+ QPtrList<KAction> aMNewOther;
+ QPtrList<KAction> aMNewAll;
+ QPtrList<KAction> aMNewConic;
+
+
+ KAction* aCancelConstruction;
+ KAction* aSelectAll;
+ KAction* aDeselectAll;
+ KAction* aInvertSelection;
+ KAction* aDeleteObjects;
+ KAction* aNewMacro;
+ KAction* aShowHidden;
+ KAction* aConfigureTypes;
+ KToggleAction* aToggleGrid;
+ KToggleAction* aToggleAxes;
+ KToggleAction* aToggleNightVision;
+ std::vector<KigGUIAction*> aActions;
+
+ /**
+ * the "token" keeps some objects that should be deleted, we only
+ * delete them after we replug the actionLists.. calling these
+ * functions should be done like:
+ * \code
+ * GUIUpdateToken t = doc->startGUIActionUpdate();
+ * doc->action[Added|Removed]( act, t );
+ * ...
+ * doc->endGUIActionUpdate( t );
+ * \endcode
+ */
+ typedef std::vector<KigGUIAction*> GUIUpdateToken;
+ GUIUpdateToken startGUIActionUpdate();
+ void actionAdded( GUIAction* a, GUIUpdateToken& t );
+ void actionRemoved( GUIAction* a, GUIUpdateToken& t );
+ void endGUIActionUpdate( GUIUpdateToken& t );
+
+ KCommandHistory* history();
+
+ void enableConstructActions( bool enabled );
+
+protected:
+ void doPrint( KPrinter& printer );
+
+ std::vector<KigWidget*> mwidgets;
+
+ KigView* m_widget;
+
+ KigDocument* mdocument;
+public:
+ const KigDocument& document() const;
+ KigDocument& document();
+
+/***************** types handling *******************/
+ void saveTypes();
+ void loadTypes();
+ void deleteTypes();
+
+};
+
+#endif // KIGPART_H
+
diff --git a/kig/kig/kig_view.cpp b/kig/kig/kig_view.cpp
new file mode 100644
index 00000000..7d36bc14
--- /dev/null
+++ b/kig/kig/kig_view.cpp
@@ -0,0 +1,593 @@
+/**
+ This file is part of Kig, a KDE program for Interactive Geometry...
+ Copyright (C) 2002 Dominique Devriese <devriese@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ USA
+**/
+
+#include "kig_view.h"
+#include "kig_view.moc"
+
+#include "kig_part.h"
+#include "kig_document.h"
+#include "kig_commands.h"
+#include "../misc/coordinate_system.h"
+#include "../misc/kiginputdialog.h"
+#include "../misc/kigpainter.h"
+#include "../modes/mode.h"
+#include "../modes/dragrectmode.h"
+
+#include <qdialog.h>
+#include <qevent.h>
+#include <qwhatsthis.h>
+#include <qlayout.h>
+#include <qscrollbar.h>
+
+#include <kdebug.h>
+#include <kcursor.h>
+#include <klocale.h>
+#include <kapplication.h>
+#include <kstdaction.h>
+#include <kaction.h>
+#include <kiconloader.h>
+
+#include <cmath>
+#include <algorithm>
+
+kdbgstream& operator<< ( kdbgstream& s, const QPoint& t )
+{
+ s << "x: " << t.x() << " y: " << t.y();
+ return s;
+}
+
+KigWidget::KigWidget( KigPart* part,
+ KigView* view,
+ QWidget* parent,
+ const char* name,
+ bool fullscreen )
+ : QWidget( parent, name,
+ fullscreen ? WStyle_Customize | WStyle_NoBorder : 0 ),
+ mpart( part ),
+ mview( view ),
+ stillPix(size()),
+ curPix(size()),
+ msi( Rect(), rect() ),
+ misfullscreen( fullscreen )
+{
+ part->addWidget(this);
+
+ setFocusPolicy(ClickFocus);
+ setBackgroundMode( Qt::NoBackground );
+ setMouseTracking(true);
+
+ curPix.resize( size() );
+ stillPix.resize( size() );
+}
+
+KigWidget::~KigWidget()
+{
+ mpart->delWidget( this );
+}
+
+void KigWidget::paintEvent(QPaintEvent*)
+{
+ updateEntireWidget();
+}
+
+void KigWidget::mousePressEvent (QMouseEvent* e)
+{
+ if( e->button() & Qt::LeftButton )
+ return mpart->mode()->leftClicked( e, this );
+ if ( e->button() & Qt::MidButton )
+ return mpart->mode()->midClicked( e, this );
+ if ( e->button() & Qt::RightButton )
+ return mpart->mode()->rightClicked( e, this );
+}
+
+void KigWidget::mouseMoveEvent (QMouseEvent* e)
+{
+ if( e->state() & Qt::LeftButton )
+ return mpart->mode()->leftMouseMoved( e, this );
+ if ( e->state() & Qt::MidButton )
+ return mpart->mode()->midMouseMoved( e, this );
+ if ( e->state() & Qt::RightButton )
+ return mpart->mode()->rightMouseMoved( e, this );
+ return mpart->mode()->mouseMoved( e, this );
+}
+
+void KigWidget::mouseReleaseEvent (QMouseEvent* e)
+{
+ if( e->state() & Qt::LeftButton )
+ return mpart->mode()->leftReleased( e, this );
+ if ( e->state() & Qt::MidButton )
+ return mpart->mode()->midReleased( e, this );
+ if ( e->state() & Qt::RightButton )
+ return mpart->mode()->rightReleased( e, this );
+}
+
+void KigWidget::updateWidget( const std::vector<QRect>& overlay )
+{
+#undef SHOW_OVERLAY_RECTS
+#ifdef SHOW_OVERLAY_RECTS
+ QPainter debug (this, this);
+ debug.setPen(Qt::yellow);
+#endif // SHOW_OVERLAY_RECTS
+ // we undo our old changes...
+ for ( std::vector<QRect>::const_iterator i = oldOverlay.begin(); i != oldOverlay.end(); ++i )
+ bitBlt( this, i->topLeft(), &curPix, *i );
+ // we add our new changes...
+ for ( std::vector<QRect>::const_iterator i = overlay.begin(); i != overlay.end(); ++i )
+ {
+ bitBlt( this, i->topLeft(), &curPix, *i );
+#ifdef SHOW_OVERLAY_RECTS
+ debug.drawRect(*i);
+#endif
+ };
+ oldOverlay = overlay;
+}
+
+void KigWidget::updateEntireWidget()
+{
+ std::vector<QRect> overlay;
+ overlay.push_back( QRect( QPoint( 0, 0 ), size() ) );
+ updateWidget( overlay );
+}
+
+void KigWidget::resizeEvent( QResizeEvent* e )
+{
+ QSize osize = e->oldSize();
+ QSize nsize = e->size();
+ Rect orect = msi.shownRect();
+
+ curPix.resize( nsize );
+ stillPix.resize( nsize );
+ msi.setViewRect( rect() );
+
+ Rect nrect( 0., 0.,
+ orect.width() * nsize.width() / osize.width(),
+ orect.height() * nsize.height() / osize.height() );
+ nrect = matchScreenShape( nrect );
+ nrect.setCenter( orect.center() );
+ msi.setShownRect( nrect );
+
+ // horrible hack... We need to somehow differentiate between the
+ // resizeEvents we get on startup, and the ones generated by the
+ // user. The first require recentering the screen, the latter
+ // don't..
+ if ( nsize.width() / osize.width() > 4 ) recenterScreen();
+
+ mpart->redrawScreen( this );
+ updateScrollBars();
+}
+
+void KigWidget::updateCurPix( const std::vector<QRect>& ol )
+{
+ // we make curPix look like stillPix again...
+ for ( std::vector<QRect>::const_iterator i = oldOverlay.begin(); i != oldOverlay.end(); ++i )
+ bitBlt( &curPix, i->topLeft(), &stillPix, *i );
+ for ( std::vector<QRect>::const_iterator i = ol.begin(); i != ol.end(); ++i )
+ bitBlt( &curPix, i->topLeft(), &stillPix, *i );
+
+ // we add ol to oldOverlay, so that part of the widget will be
+ // updated too in updateWidget...
+ std::copy( ol.begin(), ol.end(), std::back_inserter( oldOverlay ) );
+}
+
+void KigWidget::recenterScreen()
+{
+ msi.setShownRect( matchScreenShape( mpart->document().suggestedRect() ) );
+}
+
+Rect KigWidget::matchScreenShape( const Rect& r ) const
+{
+ return r.matchShape( Rect::fromQRect( rect() ) );
+}
+
+void KigWidget::slotZoomIn()
+{
+ Rect nr = msi.shownRect();
+ Coordinate c = nr.center();
+ nr /= 2;
+ nr.setCenter( c );
+ KigCommand* cd =
+ new KigCommand( *mpart,
+ i18n( "Zoom In" ) );
+ cd->addTask( new KigViewShownRectChangeTask( *this, nr ) );
+ mpart->history()->addCommand( cd );
+}
+
+void KigWidget::slotZoomOut()
+{
+ Rect nr = msi.shownRect();
+ Coordinate c = nr.center();
+ nr *= 2;
+ nr.setCenter( c );
+
+ // zooming in is undoable.. I know this isn't really correct,
+ // because the current view doesn't really belong to the document (
+ // althought KGeo and KSeg both save them along, iirc ). However,
+ // undoing a zoom or another operation affecting the window seems a
+ // bit too useful to not be available. Please try to convince me if
+ // you feel otherwise ;-)
+ KigCommand* cd =
+ new KigCommand( *mpart,
+ i18n( "Zoom Out" ) );
+ cd->addTask( new KigViewShownRectChangeTask( *this, nr ) );
+ mpart->history()->addCommand( cd );
+}
+
+void KigWidget::clearStillPix()
+{
+ stillPix.fill(Qt::white);
+ oldOverlay.clear();
+ oldOverlay.push_back ( QRect( QPoint(0,0), size() ) );
+}
+
+void KigWidget::redrawScreen( const std::vector<ObjectHolder*>& selection, bool dos )
+{
+ std::vector<ObjectHolder*> nonselection;
+ std::set<ObjectHolder*> objs = mpart->document().objectsSet();
+ std::set_difference( objs.begin(), objs.end(), selection.begin(), selection.end(),
+ std::back_inserter( nonselection ) );
+
+ // update the screen...
+ clearStillPix();
+ KigPainter p( msi, &stillPix, mpart->document() );
+ p.drawGrid( mpart->document().coordinateSystem(), mpart->document().grid(),
+ mpart->document().axes() );
+ p.drawObjects( selection, true );
+ p.drawObjects( nonselection, false );
+ updateCurPix( p.overlay() );
+ if ( dos ) updateEntireWidget();
+}
+
+const ScreenInfo& KigWidget::screenInfo() const
+{
+ return msi;
+}
+
+const Rect KigWidget::showingRect() const
+{
+ return msi.shownRect();
+}
+
+const Coordinate KigWidget::fromScreen( const QPoint& p )
+{
+ return msi.fromScreen( p );
+}
+
+double KigWidget::pixelWidth() const
+{
+ return msi.pixelWidth();
+}
+
+const Rect KigWidget::fromScreen( const QRect& r )
+{
+ return msi.fromScreen( r );
+}
+
+
+void KigWidget::updateScrollBars()
+{
+ mview->updateScrollBars();
+}
+
+KigView::KigView( KigPart* part,
+ bool fullscreen,
+ QWidget* parent,
+ const char* name )
+ : QWidget( parent, name ),
+ mlayout( 0 ), mrightscroll( 0 ), mbottomscroll( 0 ),
+ mupdatingscrollbars( false ),
+ mrealwidget( 0 ), mpart( part )
+{
+ connect( part, SIGNAL( recenterScreen() ), this, SLOT( slotInternalRecenterScreen() ) );
+
+ mlayout = new QGridLayout( this, 2, 2 );
+ mrightscroll = new QScrollBar( Vertical, this, "Right Scrollbar" );
+ // TODO: make this configurable...
+ mrightscroll->setTracking( true );
+ connect( mrightscroll, SIGNAL( valueChanged( int ) ),
+ this, SLOT( slotRightScrollValueChanged( int ) ) );
+ connect( mrightscroll, SIGNAL( sliderReleased() ),
+ this, SLOT( updateScrollBars() ) );
+ mbottomscroll = new QScrollBar( Horizontal, this, "Bottom Scrollbar" );
+ connect( mbottomscroll, SIGNAL( valueChanged( int ) ),
+ this, SLOT( slotBottomScrollValueChanged( int ) ) );
+ connect( mbottomscroll, SIGNAL( sliderReleased() ),
+ this, SLOT( updateScrollBars() ) );
+ mrealwidget = new KigWidget( part, this, this, "Kig Widget", fullscreen );
+ mlayout->addWidget( mbottomscroll, 1, 0 );
+ mlayout->addWidget( mrealwidget, 0, 0 );
+ mlayout->addWidget( mrightscroll, 0, 1 );
+
+ resize( sizeHint() );
+ mrealwidget->recenterScreen();
+ part->redrawScreen( mrealwidget );
+ updateScrollBars();
+}
+
+void KigView::updateScrollBars()
+{
+ // we update the scrollbars to reflect the new "total size" of the
+ // document... The total size is calced in entireDocumentRect().
+ // ( it is calced as a rect that contains all the points in the
+ // document, and then enlarged a bit, and scaled to match the screen
+ // width/height ratio...
+ // What we do here is tell the scroll bars what they should show as
+ // their total size..
+
+ // see the doc of this variable in the header for this...
+ mupdatingscrollbars = true;
+
+ Rect er = mrealwidget->entireDocumentRect();
+ Rect sr = mrealwidget->screenInfo().shownRect();
+
+ // we define the total rect to be the smallest rect that contains
+ // both er and sr...
+ er |= sr;
+
+ // we need ints, not doubles, so since "pixelwidth == widgetcoord /
+ // internalcoord", we use "widgetcoord/pixelwidth", which would then
+ // equal "internalcoord", which has to be an int ( by definition.. )
+ // i know, i'm a freak to think about these sorts of things... ;)
+ double pw = mrealwidget->screenInfo().pixelWidth();
+
+ // what the scrollbars reflect is the bottom resp. the left side of
+ // the shown rect. This is why the maximum value is not er.top()
+ // (which would be the maximum value of the top of the shownRect),
+ // but er.top() - sr.height(), which is the maximum value the bottom of
+ // the shownRect can reach...
+
+ int rightmin = static_cast<int>( er.bottom() / pw );
+ int rightmax = static_cast<int>( ( er.top() - sr.height() ) / pw );
+
+ mrightscroll->setMinValue( rightmin );
+ mrightscroll->setMaxValue( rightmax );
+ mrightscroll->setLineStep( (int)( sr.height() / pw / 10 ) );
+ mrightscroll->setPageStep( (int)( sr.height() / pw / 1.2 ) );
+
+ // note that since Qt has a coordinate system with the lowest y
+ // values at the top, and we have it the other way around ( i know i
+ // shouldn't have done this.. :( ), we invert the value that the
+ // scrollbar shows. This is inverted again in
+ // slotRightScrollValueChanged()...
+ mrightscroll->setValue( (int) ( rightmin + ( rightmax - ( sr.bottom() / pw ) ) ) );
+
+ mbottomscroll->setMinValue( (int)( er.left() / pw ) );
+ mbottomscroll->setMaxValue( (int)( ( er.right() - sr.width() ) / pw ) );
+ mbottomscroll->setLineStep( (int)( sr.width() / pw / 10 ) );
+ mbottomscroll->setPageStep( (int)( sr.width() / pw / 1.2 ) );
+ mbottomscroll->setValue( (int)( sr.left() / pw ) );
+
+ mupdatingscrollbars = false;
+}
+
+Rect KigWidget::entireDocumentRect() const
+{
+ return matchScreenShape( mpart->document().suggestedRect() );
+}
+
+void KigView::slotRightScrollValueChanged( int v )
+{
+ if ( ! mupdatingscrollbars )
+ {
+ // we invert the inversion that was done in updateScrollBars() (
+ // check the documentation there..; )
+ v = mrightscroll->minValue() + ( mrightscroll->maxValue() - v );
+ double pw = mrealwidget->screenInfo().pixelWidth();
+ double nb = double( v ) * pw;
+ mrealwidget->scrollSetBottom( nb );
+ };
+}
+
+void KigView::slotBottomScrollValueChanged( int v )
+{
+ if ( ! mupdatingscrollbars )
+ {
+ double pw = mrealwidget->screenInfo().pixelWidth();
+ double nl = double( v ) * pw;
+ mrealwidget->scrollSetLeft( nl );
+ };
+}
+
+void KigWidget::scrollSetBottom( double rhs )
+{
+ Rect sr = msi.shownRect();
+ Coordinate bl = sr.bottomLeft();
+ bl.y = rhs;
+ sr.setBottomLeft( bl );
+ msi.setShownRect( sr );
+ mpart->redrawScreen( this );
+}
+
+void KigWidget::scrollSetLeft( double rhs )
+{
+ Rect sr = msi.shownRect();
+ Coordinate bl = sr.bottomLeft();
+ bl.x = rhs;
+ sr.setBottomLeft( bl );
+ msi.setShownRect( sr );
+ mpart->redrawScreen( this );
+}
+
+const ScreenInfo& KigView::screenInfo() const
+{
+ return mrealwidget->screenInfo();
+}
+
+KigView::~KigView()
+{
+}
+
+KigWidget* KigView::realWidget() const
+{
+ return mrealwidget;
+}
+
+const KigDocument& KigWidget::document() const
+{
+ return mpart->document();
+}
+
+QSize KigWidget::sizeHint() const
+{
+ return QSize( 630, 450 );
+}
+
+void KigWidget::wheelEvent( QWheelEvent* e )
+{
+ int delta = e->delta();
+ Qt::Orientation orient = e->orientation();
+ if ( orient == Qt::Vertical )
+ mview->scrollVertical( delta );
+ else
+ mview->scrollHorizontal( delta );
+}
+
+void KigView::scrollHorizontal( int delta )
+{
+ if ( delta >= 0 )
+ for ( int i = 0; i < delta; i += 120 )
+ mbottomscroll->subtractLine();
+ else
+ for ( int i = 0; i >= delta; i -= 120 )
+ mbottomscroll->addLine();
+}
+
+void KigView::scrollVertical( int delta )
+{
+ if ( delta >= 0 )
+ for ( int i = 0; i < delta; i += 120 )
+ mrightscroll->subtractLine();
+ else
+ for ( int i = 0; i >= delta; i -= 120 )
+ mrightscroll->addLine();
+}
+
+bool KigWidget::isFullScreen() const
+{
+ return misfullscreen;
+}
+
+void KigView::slotZoomIn()
+{
+ mrealwidget->slotZoomIn();
+}
+
+void KigView::slotZoomOut()
+{
+ mrealwidget->slotZoomOut();
+}
+
+void KigWidget::slotRecenterScreen()
+{
+ Rect nr = mpart->document().suggestedRect();
+ KigCommand* cd =
+ new KigCommand( *mpart,
+ i18n( "Recenter View" ) );
+
+ cd->addTask( new KigViewShownRectChangeTask( *this, nr ) );
+ mpart->history()->addCommand( cd );
+}
+
+void KigView::toggleFullScreen()
+{
+ mrealwidget->setFullScreen( ! mrealwidget->isFullScreen() );
+ if ( mrealwidget->isFullScreen() )
+ topLevelWidget()->showFullScreen();
+ else
+ topLevelWidget()->showNormal();
+}
+
+void KigWidget::setFullScreen( bool f )
+{
+ misfullscreen = f;
+}
+
+void KigWidget::zoomRect()
+{
+ mpart->emitStatusBarText( i18n( "Select the rectangle that should be shown." ) );
+ DragRectMode d( *mpart, *this );
+ mpart->runMode( &d );
+ if ( ! d.cancelled() )
+ {
+ Rect nr = d.rect();
+ KigCommand* cd =
+ new KigCommand( *mpart,
+ i18n( "Change Shown Part of Screen" ) );
+
+ cd->addTask( new KigViewShownRectChangeTask( *this, nr ) );
+ mpart->history()->addCommand( cd );
+ };
+
+ mpart->redrawScreen( this );
+ updateScrollBars();
+}
+
+void KigView::zoomRect()
+{
+ mrealwidget->zoomRect();
+}
+
+void KigWidget::setShowingRect( const Rect& r )
+{
+ msi.setShownRect( r.matchShape( Rect::fromQRect( rect() ) ) );
+}
+
+void KigView::slotRecenterScreen()
+{
+ mrealwidget->slotRecenterScreen();
+}
+
+void KigView::slotInternalRecenterScreen()
+{
+ mrealwidget->recenterScreen();
+}
+
+void KigWidget::zoomArea()
+{
+// mpart->emitStatusBarText( i18n( "Select the area that should be shown." ) );
+ Rect oldrect = showingRect();
+ Coordinate tl = oldrect.topLeft();
+ Coordinate br = oldrect.bottomRight();
+ bool ok = true;
+ KigInputDialog::getTwoCoordinates( i18n( "Select Zoom Area" ),
+ i18n( "Select the zoom area by entering the coordinates of "
+ "the upper left corner and the lower right corner." ) +
+ QString::fromLatin1("<br>") +
+ mpart->document().coordinateSystem().coordinateFormatNoticeMarkup(),
+ this, &ok, mpart->document(), &tl, &br );
+ if ( ok )
+ {
+ Coordinate nc1( tl.x, br.y );
+ Coordinate nc2( br.x, tl.y );
+ Rect nr( nc1, nc2 );
+ KigCommand* cd = new KigCommand( *mpart, i18n( "Change Shown Part of Screen" ) );
+
+ cd->addTask( new KigViewShownRectChangeTask( *this, nr ) );
+ mpart->history()->addCommand( cd );
+ }
+
+ mpart->redrawScreen( this );
+ updateScrollBars();
+}
+
+void KigView::zoomArea()
+{
+ mrealwidget->zoomArea();
+}
+
diff --git a/kig/kig/kig_view.h b/kig/kig/kig_view.h
new file mode 100644
index 00000000..7970e088
--- /dev/null
+++ b/kig/kig/kig_view.h
@@ -0,0 +1,274 @@
+/**
+ This file is part of Kig, a KDE program for Interactive Geometry...
+ Copyright (C) 2002 Dominique Devriese <devriese@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ USA
+**/
+
+
+#ifndef KIG_VIEW_H
+#define KIG_VIEW_H
+
+#include <qwidget.h>
+#include <qpixmap.h>
+
+#include <kparts/part.h>
+
+#include <vector>
+
+#include "../objects/object_holder.h"
+#include "../misc/rect.h"
+#include "../misc/screeninfo.h"
+
+class QGridLayout;
+class QScrollBar;
+
+class KigDocument;
+class KigView;
+
+/**
+ * This class is the real widget showing the document. The other is a
+ * wrapper, that has the scrollbars... I'm not using QScrollView
+ * cause i've been having problems with that, and it's easier to do
+ * the work myself...
+ * Internally, this is basically a dumb class, which is manipulated by
+ * KigMode's. All events are forwarded to them.
+ */
+class KigWidget : public QWidget
+{
+ Q_OBJECT
+
+ KigPart* mpart;
+ KigView* mview;
+
+ // we reimplement these from QWidget to suit our needs
+ void mousePressEvent( QMouseEvent* e );
+ void mouseMoveEvent( QMouseEvent* e );
+ void mouseReleaseEvent( QMouseEvent* e );
+ void paintEvent( QPaintEvent* e );
+ void wheelEvent( QWheelEvent* e );
+ void resizeEvent( QResizeEvent* );
+ QSize sizeHint() const;
+
+ /**
+ * this is called to match a rect's dimensions to the dimensions of
+ * the window before we set mViewRect to it. This is done cause we
+ * always want circles to look like circles etc...
+ */
+ Rect matchScreenShape( const Rect& r ) const;
+
+public:
+ /**
+ * what do the still objects look like
+ * wondering if this is appropriate, maybe it should be part of
+ * MovingMode ?
+ */
+ QPixmap stillPix;
+ /**
+ * temporary, gets bitBlt'd (copied) onto the widget
+ * (to avoid flickering)
+ */
+ QPixmap curPix;
+
+protected:
+ std::vector<QRect> oldOverlay;
+
+ /**
+ * this is a class that maps from our widget coordinates to the
+ * document's coordinates ( and back ).
+ */
+ ScreenInfo msi;
+
+ /**
+ * is this a full-screen widget ?
+ */
+ bool misfullscreen;
+
+public:
+ /**
+ * standard qwidget constructor. if fullscreen is true, we're a
+ * fullscreen widget.
+ */
+ KigWidget( KigPart* doc,
+ KigView* view,
+ QWidget* parent = 0,
+ const char* name = 0,
+ bool fullscreen = false
+ );
+ ~KigWidget();
+
+ bool isFullScreen() const;
+ void setFullScreen( bool f );
+
+ const KigView* view() const {
+ return mview;
+ }
+
+ KigView* view() {
+ return mview;
+ }
+
+ /**
+ * The following are functions used by KigMode's to tell us to draw
+ * stuff...
+ * i tried to optimise the drawing as much as possible, using
+ * much ideas from kgeo
+ * DOUBLE BUFFERING:
+ * we don't draw on the widget directly, we draw on a QPixmap (
+ * curPix ), and bitBlt that onto the widget to avoid flickering.
+ * TRIPLE BUFFERING:
+ * we also currently keep an extra pixmap of what the widget looks
+ * like without objects that are moving... i'm currently wondering
+ * whether this isn't a performance loss rather than a gain, but
+ * well, i haven't done any measurements (yet ?), so for now it
+ * stays in...
+ * OVERLAYS
+ * Another thing: it turns out that working on the pixmaps isn't
+ * that slow, but working on the widget is. So we try to reduce the
+ * amount of work we spend on the widget. (i got this idea from
+ * kgeo, all credits for this go to marc.bartsch@web.de)
+ * on drawing, KigPainter tells us (appendOverlay) for everything it
+ * draws what rects it draws in, so we know on updating the widget (
+ * updateWidget() that the rest is still ok and doesn't need to be
+ * bitBlt'd again on the widget...
+ */
+
+ /**
+ * clear stillPix...
+ */
+ void clearStillPix();
+ /**
+ * update curPix (bitBlt stillPix onto curPix..)
+ */
+ void updateCurPix( const std::vector<QRect>& = std::vector<QRect>());
+
+ /**
+ * this means bitBlting curPix on the actual widget...
+ */
+ void updateWidget( const std::vector<QRect>& = std::vector<QRect>() );
+ void updateEntireWidget();
+
+ /**
+ * Mapping between Internal Coordinate Systems
+ * there are two coordinate systems:
+ * 1 the widget's coordinates: these are simple int's from (0,0) in
+ * the topleft of the widget to size() in the bottomRight...
+ * 2 the document's coordinates: these are the coordinates used by
+ * the KigDocument. Objects only know of their coordinates as
+ * related to this system.
+ * These are mapped by the KigView using the ScreenInfo class.
+ */
+ const Rect showingRect() const;
+ void setShowingRect( const Rect& r );
+
+ const Coordinate fromScreen( const QPoint& p );
+ const Rect fromScreen( const QRect& r );
+ double pixelWidth() const;
+
+ /**
+ * the part of the document we're currently showing
+ * i.e. a rectangle of the document (which has its own coordinate
+ * system) which is mapped onto the widget.
+ */
+ const ScreenInfo& screenInfo() const;
+
+ Rect entireDocumentRect() const;
+
+ void updateScrollBars();
+
+ void scrollSetBottom( double rhs );
+ void scrollSetLeft( double rhs );
+
+ const KigDocument& document() const;
+
+public:
+ /**
+ * this recenters the screen, that is, resets the shown rect to
+ * mpart->document().suggestedRect()..
+ */
+ void recenterScreen();
+ /**
+ * this gets called if the user clicks the recenter screen button.
+ * It adds a KigCommand to the CommandHistory that recenters the
+ * screen..
+ */
+ void slotRecenterScreen();
+
+ // called when the user clicks the appropriate buttons..
+ void slotZoomIn();
+ void slotZoomOut();
+
+ void zoomRect();
+ void zoomArea();
+
+ void redrawScreen( const std::vector<ObjectHolder*>& selection, bool paintOnWidget = true );
+};
+
+/**
+ * This class is a wrapper for KigWidget. It has some actions
+ * that belong here, and not in the part. It also maintains the
+ * scrollbars, but it doesn't manipulate them itself. It forwards
+ * most of its functionality to KigWidget...
+ */
+class KigView
+ : public QWidget
+{
+ Q_OBJECT
+
+ QGridLayout* mlayout;
+ QScrollBar* mrightscroll;
+ QScrollBar* mbottomscroll;
+
+ /**
+ * apparently, QScrollBar also emits its signals when you update it
+ * manually, so we ignore them while we're in \ref updateScrollBars()...
+ */
+ bool mupdatingscrollbars;
+
+ KigWidget* mrealwidget;
+ KigPart* mpart;
+
+public:
+ KigView( KigPart* part,
+ bool fullscreen = false,
+ QWidget* parent = 0,
+ const char* name = 0
+ );
+ ~KigView();
+
+ void setupActions();
+
+ const ScreenInfo& screenInfo() const;
+
+ KigWidget* realWidget() const;
+ void scrollHorizontal( int delta );
+ void scrollVertical( int delta );
+
+public slots:
+ void updateScrollBars();
+ void slotZoomIn();
+ void slotZoomOut();
+ void zoomRect();
+ void zoomArea();
+ void slotInternalRecenterScreen();
+ void slotRecenterScreen();
+ void toggleFullScreen();
+
+private slots:
+ void slotRightScrollValueChanged( int );
+ void slotBottomScrollValueChanged( int );
+};
+#endif
diff --git a/kig/kig/kigpartui.rc b/kig/kig/kigpartui.rc
new file mode 100644
index 00000000..7e594416
--- /dev/null
+++ b/kig/kig/kigpartui.rc
@@ -0,0 +1,288 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui name="kig_part" version="10">
+ <MenuBar>
+ <Menu name="file">
+ <text>&amp;File</text>
+ <Action name="file_save" />
+ <Action name="file_save_as" />
+ <Separator />
+ <Action name="file_print" />
+ <Action name="file_print_preview" />
+ <Separator />
+ <Action name="file_export" />
+ <Separator />
+ </Menu>
+ <Menu name="edit">
+ <text>&amp;Edit</text>
+ <Action name="edit_undo" />
+ <Action name="edit_redo" />
+ <Separator />
+ <Action name="edit_select_all" />
+ <Action name="edit_deselect" />
+ <Action name="edit_invert_selection" />
+ <Separator/>
+ <Action name="edit_unhide_all" />
+ </Menu>
+ <Menu name="view">
+ <text>&amp;View</text>
+ <Action name="view_zoom_in" />
+ <Action name="view_zoom_out" />
+ <Action name="view_fit_to_page" />
+ <Action name="view_select_shown_rect" />
+ <Action name="view_zoom_area" />
+ </Menu>
+ <Menu name="objects">
+ <text>&amp;Objects</text>
+ <Menu name="new_point" icon="point">
+ <text>&amp;Points</text>
+ <Action name="objects_new_normalpoint" />
+ <Action name="objects_new_midpoint" />
+ <Action name="objects_new_intersection" />
+ <Action name="objects_new_point_xy" />
+ <Action name="objects_new_translatedpoint" />
+ <Action name="objects_new_rotatedpoint" />
+ <Action name="objects_new_mirrorpoint" />
+ <ActionList name="user_point_types" />
+ </Menu>
+ <Menu name="new_line" icon="line">
+ <text>&amp;Lines</text>
+ <Action name="objects_new_linettp" />
+ <Action name="objects_new_lineperpend" />
+ <Action name="objects_new_lineparallel" />
+ <Action name="objects_new_ray" />
+ <Action name="objects_new_linebyvector" />
+ <Action name="objects_new_halflinebyvector" />
+ <ActionList name="user_line_types" />
+ </Menu>
+ <Menu name="new_circle" icon="circlebps">
+ <text>&amp;Circles &amp;&amp; Arcs</text>
+ <Action name="objects_new_circlebcp" />
+ <Action name="objects_new_circlebtp" />
+ <Action name="objects_new_circlebps" />
+ <Action name="objects_new_circlebpd" />
+ <Action name="objects_new_circlebcl" />
+ <Action name="objects_new_arcbtp" />
+ <Action name="objects_new_arcbcpa" />
+ <ActionList name="user_circle_types" />
+ </Menu>
+ <Menu name="new_poligon" icon="hexagonbcv">
+ <text>Poly&amp;gons</text>
+ <Action name="objects_new_trianglebtp" />
+ <Action name="objects_new_polygonbnp" />
+ <Action name="objects_new_polygonbcv" />
+ <Action name="objects_new_equitriangle" />
+ <Action name="objects_new_square" />
+ <Action name="objects_new_polygonvertices" />
+ <Action name="objects_new_polygonsides" />
+ <Action name="objects_new_convexhull" />
+ </Menu>
+ <Menu name="new_vector" icon="vector">
+ <text>&amp;Vectors &amp;&amp; Segments</text>
+ <Action name="objects_new_segment" />
+ <Action name="objects_new_segment_axis" />
+ <Action name="objects_new_vector" />
+ <Action name="objects_new_vectorsum" />
+ <Action name="objects_new_vectordifference" />
+ <ActionList name="user_segment_types" />
+ </Menu>
+ <Menu name="new_conic" icon="conicb5p">
+ <text>Co&amp;nics &amp;&amp; Cubics</text>
+ <Action name="objects_new_ellipsebffp" />
+ <Action name="objects_new_hyperbolabffp" />
+ <Action name="objects_new_conicb5p" />
+ <Action name="objects_new_parabolabtp" />
+ <ActionList name="user_conic_types" />
+ <Menu name="new_moreconics" icon="conicsradicalline">
+ <text>More Conics</text>
+ <Action name="objects_new_parabolabdp" />
+ <Action name="objects_new_equilateralhyperbolab4p" />
+ <Action name="objects_new_conicbdfp" />
+ <Action name="objects_new_conicbaap" />
+ <Action name="objects_new_linepolar" />
+ <Action name="objects_new_lineconicasymptotes" />
+ <Action name="objects_new_pointpolar" />
+ <Action name="objects_new_linedirectrix" />
+ <Action name="objects_new_lineconicradical" />
+ </Menu>
+ <Separator />
+ <Menu name="new_cubic">
+ <text>Cu&amp;bics</text>
+ <Action name="objects_new_cubicb9p" />
+ <Action name="objects_new_cubicnodeb6p" />
+ <Action name="objects_new_cubiccuspb4p" />
+ </Menu>
+ </Menu>
+ <Menu name="new_angle" icon="angle">
+ <text>&amp;Angles</text>
+ <Action name="objects_new_angle" />
+ <Action name="objects_new_angle_bisector" />
+ </Menu>
+ <Menu name="new_transformation" icon="centralsymmetry">
+ <text>&amp;Transformations</text>
+ <Action name="objects_new_translation" />
+ <Action name="objects_new_pointreflection" />
+ <Action name="objects_new_linereflection" />
+ <Action name="objects_new_rotation" />
+ <Action name="objects_new_scalingovercenter" />
+ <Action name="objects_new_scalingovercenter2" />
+ <Action name="objects_new_scalingoverline" />
+ <Action name="objects_new_scalingoverline2" />
+ <Action name="objects_new_similitude" />
+ <Action name="objects_new_inversion" />
+ <Action name="objects_new_harmonichomology" />
+ <Action name="objects_new_genericaffinity" />
+ <Action name="objects_new_genericprojectivity" />
+ <Action name="objects_new_castshadow" />
+ <Action name="objects_new_projectiverotation" />
+ </Menu>
+ <Menu name="new_differentialgeometry" icon="tangent">
+ <text>&amp;Differential geometry</text>
+ <Action name="objects_new_tangent" />
+ <Action name="objects_new_centerofcurvature" />
+ <Action name="objects_new_osculatingcircle" />
+ <Action name="objects_new_evolute" />
+ </Menu>
+ <Menu name="new_test" icon="test">
+ <text>T&amp;ests</text>
+ <Action name="objects_new_areparallel" />
+ <Action name="objects_new_areorthogonal" />
+ <Action name="objects_new_arecollinear" />
+ <Action name="objects_new_containstest" />
+ <Action name="objects_new_distancetest" />
+ <Action name="objects_new_vectorequalitytest" />
+ <Action name="objects_new_inpolygontest" />
+ <Action name="objects_new_convexpolygontest" />
+ </Menu>
+ <Menu name="new_other">
+ <text>&amp;Other</text>
+ <Action name="objects_new_locus" />
+ <Action name="objects_new_textlabel" />
+ <Action name="objects_new_measuretransport" />
+ <Action name="objects_new_script_python" />
+ <ActionList name="user_other_types" />
+ </Menu>
+ <Separator />
+ <Action name="delete_objects" />
+ <Action name="cancel_construction" />
+ </Menu>
+ <Menu name="types">
+ <text>&amp;Types</text>
+ <Action name="macro_action" />
+ <Action name="types_edit" />
+ </Menu>
+ <Menu name="settings">
+ <Action name="fullscreen" />
+ <Action name="settings_set_coordinate_system" />
+ <Action name="settings_show_grid" />
+ <Action name="settings_show_axes" />
+ <Action name="settings_toggle_nightvision" />
+ </Menu>
+ </MenuBar>
+ <ToolBar name="mainToolBar">
+ <text>Main Toolbar</text>
+ <Action name="file_save" />
+ <Action name="file_save_as" />
+ <Separator />
+ <Action name="file_print" />
+ <Separator />
+ <Action name="edit_undo"/>
+ <Action name="edit_redo"/>
+ <Separator />
+ <Action name="delete_objects"/>
+ <Action name="cancel_construction"/>
+ <Action name="macro_action"/>
+ </ToolBar>
+ <ToolBar name="points_toolbar" position="left">
+ <text>Points</text>
+ <Action name="objects_new_normalpoint" />
+ <Action name="objects_new_point_xy" />
+ <Action name="objects_new_intersection" />
+ <Action name="objects_new_midpoint" />
+ <Action name="objects_new_mirrorpoint" />
+ <Action name="objects_new_rotatedpoint" />
+ <Action name="objects_new_translatedpoint" />
+ <ActionList name="user_point_types" />
+ </ToolBar>
+ <ToolBar name="line_toolbar" position="left">
+ <text>Lines</text>
+ <Action name="objects_new_linettp" />
+ <Action name="objects_new_ray" />
+ <Action name="objects_new_lineperpend" />
+ <Action name="objects_new_lineparallel" />
+ <Action name="objects_new_linebyvector" />
+ <Action name="objects_new_halflinebyvector" />
+ <ActionList name="user_line_types" />
+ </ToolBar>
+ <ToolBar name="vectseg_toolbar" position="left">
+ <text>Vectors &amp;&amp; Segments</text>
+ <Action name="objects_new_segment" />
+ <Action name="objects_new_segment_axis" />
+ <Action name="objects_new_vector" />
+ <Action name="objects_new_vectorsum" />
+ <ActionList name="user_segment_types" />
+ </ToolBar>
+ <ToolBar name="circle_toolbar" position="left">
+ <text>Circles &amp;&amp; Arcs</text>
+ <Action name="objects_new_circlebcp" />
+ <Action name="objects_new_circlebtp" />
+ <Action name="objects_new_circlebps" />
+ <Action name="objects_new_circlebpd" />
+ <Action name="objects_new_arcbtp" />
+ <ActionList name="user_circle_types" />
+ </ToolBar>
+ <ToolBar name="conic_toolbar" position="left">
+ <text>Conics</text>
+ <Action name="objects_new_ellipsebffp" />
+ <Action name="objects_new_hyperbolabffp" />
+ <Action name="objects_new_parabolabtp" />
+ <Action name="objects_new_conicb5p" />
+ <ActionList name="user_conic_types" />
+ <Action name="objects_new_lineconicradical" />
+ </ToolBar>
+ <ToolBar name="angles_toolbar" position="left">
+ <text>Angles</text>
+ <Action name="objects_new_angle" />
+ <Action name="objects_new_angle_bisector" />
+ </ToolBar>
+ <ToolBar name="transformation_toolbar" position="right">
+ <text>Transformations</text>
+ <Action name="objects_new_translation" />
+ <Action name="objects_new_pointreflection" />
+ <Action name="objects_new_linereflection" />
+ <Action name="objects_new_rotation" />
+ <Action name="objects_new_scalingovercenter" />
+ <Action name="objects_new_scalingoverline" />
+ <Action name="objects_new_similitude" />
+ <Action name="objects_new_inversion" />
+ <Action name="objects_new_harmonichomology" />
+ <Action name="objects_new_genericaffinity" />
+ <Action name="objects_new_genericprojectivity" />
+ </ToolBar>
+ <ToolBar name="tests_toolbar" position="right">
+ <text>Tests</text>
+ <Action name="objects_new_areparallel" />
+ <Action name="objects_new_areorthogonal" />
+ <Action name="objects_new_arecollinear" />
+ <Action name="objects_new_containstest" />
+ <Action name="objects_new_distancetest" />
+ <Action name="objects_new_vectorequalitytest" />
+ <Action name="objects_new_inpolygontest" />
+ <Action name="objects_new_convexpolygontest" />
+ </ToolBar>
+ <ToolBar name="rest_toolbar" position="left">
+ <text>Other Objects</text>
+ <Action name="objects_new_locus" />
+ <Action name="objects_new_textlabel" />
+ <Action name="objects_new_script_python" />
+ <ActionList name="user_other_types" />
+ </ToolBar>
+ <ToolBar name="view_toolbar">
+ <text>View</text>
+ <Action name="view_zoom_in" />
+ <Action name="view_zoom_out" />
+ <Action name="fullscreen" />
+ <Action name="view_fit_to_page" />
+ <Action name="view_select_shown_rect" />
+ <Action name="view_zoom_area" />
+ </ToolBar>
+</kpartgui>
diff --git a/kig/kig/kigui.rc b/kig/kig/kigui.rc
new file mode 100644
index 00000000..db90b0d2
--- /dev/null
+++ b/kig/kig/kigui.rc
@@ -0,0 +1,40 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui name="kig_shell" version="3">
+<MenuBar>
+ <Menu name="file" noMerge="1"><text>&amp;File</text>
+ <Action name="file_new"/>
+ <Action name="file_open"/>
+ <Action name="file_open_recent"/>
+ <Separator />
+ <Merge />
+ <Action name="file_quit"/>
+ </Menu>
+ <Merge />
+ <Menu name="settings" noMerge="1"><text>&amp;Settings</text>
+ <Action name="options_show_toolbar"/>
+ <Merge name="StandardToolBarMenuHandler" />
+ <Action name="options_show_statusbar"/>
+ <Merge />
+ <Separator/>
+ <Action name="options_configure_keybinding"/>
+ <Action name="options_configure_toolbars"/>
+ </Menu>
+ <Menu name="help" noMerge="1"><text>&amp;Help</text>
+ <Action name="help_contents"/>
+ <Action name="help_whats_this"/>
+ <Separator/>
+ <Action name="help_tipofday"/>
+ <Separator/>
+ <Action name="help_report_bug"/>
+ <Separator/>
+ <Action name="help_about_app"/>
+ <Action name="help_about_kde"/>
+ </Menu>
+</MenuBar>
+<ToolBar name="mainToolBar" noMerge="1"><text>Main Toolbar</text>
+ <Action name="file_new"/>
+ <Action name="file_open"/>
+ <Separator/>
+ <Merge />
+</ToolBar>
+</kpartgui>
diff --git a/kig/kig/main.cpp b/kig/kig/main.cpp
new file mode 100644
index 00000000..d0a70404
--- /dev/null
+++ b/kig/kig/main.cpp
@@ -0,0 +1,144 @@
+/**
+ This file is part of Kig, a KDE program for Interactive Geometry...
+ Copyright (C) 2002 Dominique Devriese <devriese@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ USA
+**/
+
+#include "kig.h"
+
+#include <kuniqueapplication.h>
+#include <kaboutdata.h>
+#include <kcmdlineargs.h>
+#include <klocale.h>
+#include <klibloader.h>
+#include <kdebug.h>
+
+#include "aboutdata.h"
+
+static KCmdLineOptions options[] =
+ {
+ { "c", 0, 0 },
+ { "convert-to-native", I18N_NOOP( "Do not show a GUI. Convert the specified file to the native Kig format. Output goes to stdout unless --outfile is specified." ), 0 },
+ { "o", 0, 0 },
+ { "outfile <file>", I18N_NOOP( "File to output the created native file to. '-' means output to stdout. Default is stdout as well." ), 0 },
+ { "+[URL]", I18N_NOOP( "Document to open" ), 0 },
+ KCmdLineLastOption
+ };
+
+class KigApplication
+ : public KUniqueApplication
+{
+public:
+ KigApplication( bool gui = true );
+ int newInstance();
+ void handleArgs( KCmdLineArgs* args );
+};
+
+KigApplication::KigApplication( bool gui )
+ : KUniqueApplication( gui, gui )
+{
+}
+
+int KigApplication::newInstance()
+{
+ static bool first = true;
+ if (isRestored() && first)
+ {
+ first = false;
+ return 0;
+ }
+ first = false;
+
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+ handleArgs(args);
+ args->clear();
+ return 0;
+}
+
+void KigApplication::handleArgs( KCmdLineArgs* args )
+{
+ if ( args->count() == 0 )
+ {
+ Kig *widget = new Kig;
+ widget->show();
+ }
+ else
+ {
+ for (int i = 0; i < args->count(); i++ )
+ {
+ Kig *widget = new Kig;
+ widget->show();
+ widget->load( args->url( i ) );
+ }
+ }
+}
+
+static int convertToNative( const KURL& file, const QCString& outfile )
+{
+ KigApplication app( false );
+ KLibrary* library = KLibLoader::self()->globalLibrary( "libkigpart" );
+ int ( *converterfunction )( const KURL&, const QCString& );
+ converterfunction = ( int ( * )( const KURL&, const QCString& ) ) library->symbol( "convertToNative" );
+ if ( !converterfunction )
+ {
+ kdError() << "Error: broken Kig installation: different library and application version !" << endl;
+ return -1;
+ }
+ return (*converterfunction)( file, outfile );
+}
+
+int main(int argc, char **argv)
+{
+ KAboutData *about = kigAboutData( "kig", I18N_NOOP("Kig") );
+
+ KCmdLineArgs::init(argc, argv, about);
+ KCmdLineArgs::addCmdLineOptions( options );
+ KigApplication::addCmdLineOptions();
+
+ KCmdLineArgs* args = KCmdLineArgs::parsedArgs();
+ if ( args->isSet( "convert-to-native" ) )
+ {
+ QCString outfile = args->getOption( "outfile" );
+ if ( outfile.isNull() )
+ outfile = "-";
+
+ if ( args->count() == 0 )
+ {
+ kdError() << "Error: --convert-to-native specified without a file to convert." << endl;
+ return -1;
+ }
+ if ( args->count() > 1 )
+ {
+ kdError() << "Error: --convert-to-native specified with more than one file to convert." << endl;
+ return -1;
+ }
+ return convertToNative( args->url( 0 ), outfile );
+ }
+ else
+ {
+ if ( args->isSet( "outfile" ) )
+ {
+ kdError() << "Error: --outfile specified without convert-to-native." << endl;
+ return -1;
+ }
+ KigApplication app;
+
+ // see if we are starting with session management
+ if (app.isRestored()) RESTORE(Kig)
+ return app.exec();
+ }
+}