diff --git a/kig/kig_part.cpp b/kig/kig_part.cpp index 68e0efb6..ff53f2ae 100644 --- a/kig/kig_part.cpp +++ b/kig/kig_part.cpp @@ -1,1152 +1,1170 @@ /** This file is part of Kig, a KDE program for Interactive Geometry... Copyright (C) 2002 Dominique Devriese 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 #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/kigcoordinateprecisiondialog.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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; static const QString typesFile = QStringLiteral("macros.kigt"); QStringList getDataFiles( const QString & folder ) { QStringList dataFiles; const QStringList allFolders = QStandardPaths::locateAll( QStandardPaths::DataLocation, folder, QStandardPaths::LocateDirectory ); for( const QString & folderPath : allFolders ) { QDirIterator folderIterator( folderPath, QDirIterator::Subdirectories ); while ( folderIterator.hasNext() ) { const QString fileName = folderIterator.next(); if ( fileName.endsWith( QLatin1String( ".kigt" ) ) ) { dataFiles << fileName; } } } return dataFiles; } // export this library... K_PLUGIN_FACTORY( KigPartFactory, registerPlugin< KigPart >(); ) SetCoordinateSystemAction::SetCoordinateSystemAction( KigPart& d, KActionCollection* parent ) : KSelectAction( i18n( "&Set Coordinate System" ), &d), md( d ) { setItems( CoordinateSystemFactory::names() ); setCurrentItem( md.document().coordinateSystem().id() ); connect( this, SIGNAL(triggered(int)), this, SLOT(slotActivated(int)) ); if(parent) parent->addAction(QStringLiteral("settings_set_coordinate_system"), this); } void SetCoordinateSystemAction::slotActivated( int index ) { CoordinateSystem* sys = CoordinateSystemFactory::build( index ); assert( sys ); md.history()->push( KigCommand::changeCoordSystemCommand( md, sys ) ); setCurrentItem( index ); } class KigPrintDialogPage : public QWidget { public: KigPrintDialogPage( QWidget* parent = 0 ); ~KigPrintDialogPage(); bool printShowGrid(); void setPrintShowGrid( bool status ); bool printShowAxes(); void setPrintShowAxes( bool status ); bool isValid( QString& ); private: QCheckBox *showgrid; QCheckBox *showaxes; }; KigPrintDialogPage::KigPrintDialogPage( QWidget* parent ) : QWidget( parent ) { setWindowTitle( i18n( "Kig Options" ) ); QVBoxLayout* vl = new QVBoxLayout( this ); 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() { } bool KigPrintDialogPage::printShowGrid() { return showgrid->isChecked(); } void KigPrintDialogPage::setPrintShowGrid( bool status ) { showgrid->setChecked( status ); } bool KigPrintDialogPage::printShowAxes() { return showaxes->isChecked(); } void KigPrintDialogPage::setPrintShowAxes( bool status ) { showaxes->setChecked( status ); } bool KigPrintDialogPage::isValid( QString& ) { return true; } KigPart::KigPart( QWidget *parentWidget, QObject *parent, const QVariantList& ) : KParts::ReadWritePart( parent ), mMode( 0 ), mRememberConstruction( 0 ), mdocument( new KigDocument() ) { // we need an instance setComponentData( kigAboutData( "kig", I18N_NOOP( "KigPart" ) ) ); mMode = new NormalMode( *this ); // we need a widget, to actually show the document m_widget = new KigView( this, false, parentWidget ); m_widget->setObjectName( QStringLiteral("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(QStringLiteral("kigpartui.rc")); // our types... setupTypes(); // construct our command history mhistory = new QUndoStack(); KUndoActions::createUndoAction( mhistory, actionCollection() ); KUndoActions::createRedoAction( mhistory, actionCollection() ); connect( mhistory, &QUndoStack::cleanChanged, this, &KigPart::setHistoryClean ); // we are read-write by default setReadWrite(true); setModified (false); GUIActionList::instance()->regDoc( this ); } void KigPart::setupActions() { // save actions.. (void) KStandardAction::saveAs(this, SLOT(fileSaveAs()), actionCollection()); (void) KStandardAction::save(this, SLOT(fileSave()), actionCollection()); // print actions (void) KStandardAction::print( this, SLOT(filePrint()), actionCollection() ); (void) KStandardAction::printPreview( this, SLOT(filePrintPreview()), actionCollection() ); // selection actions aSelectAll = KStandardAction::selectAll( this, SLOT(slotSelectAll()), actionCollection() ); aDeselectAll = KStandardAction::deselect( this, SLOT(slotDeselectAll()), actionCollection() ); aInvertSelection = new QAction(i18n("Invert Selection"), this); actionCollection()->addAction(QStringLiteral("edit_invert_selection"), aInvertSelection ); connect(aInvertSelection, &QAction::triggered, this, &KigPart::slotInvertSelection); // we need icons... KIconLoader* l = iconLoader(); aDeleteObjects = new QAction(QIcon::fromTheme(QStringLiteral("edit-delete")), i18n("&Delete Objects"), this); actionCollection()->addAction(QStringLiteral("delete_objects"), aDeleteObjects ); connect(aDeleteObjects, &QAction::triggered, this, &KigPart::deleteObjects); actionCollection()->setDefaultShortcut(aDeleteObjects, QKeySequence(Qt::Key_Delete)); aDeleteObjects->setToolTip(i18n("Delete the selected objects")); aCancelConstruction = new QAction(QIcon::fromTheme(QStringLiteral("process-stop")), i18n("Cancel Construction"), this); actionCollection()->addAction(QStringLiteral("cancel_construction"), aCancelConstruction ); connect(aCancelConstruction, &QAction::triggered, this, &KigPart::cancelConstruction); actionCollection()->setDefaultShortcut(aCancelConstruction, QKeySequence(Qt::Key_Escape)); aCancelConstruction->setToolTip( i18n("Cancel the construction of the object being constructed")); aCancelConstruction->setEnabled(false); aRepeatLastConstruction = new QAction(QIcon::fromTheme(QStringLiteral("system-run")), i18n("Repeat Construction"), this); actionCollection()->addAction(QStringLiteral("repeat_last_construction"), aRepeatLastConstruction ); connect(aRepeatLastConstruction, &QAction::triggered, this, &KigPart::repeatLastConstruction); actionCollection()->setDefaultShortcut(aRepeatLastConstruction, QKeySequence(Qt::Key_Z)); aRepeatLastConstruction->setToolTip( i18n("Repeat the last construction (with new data)")); aRepeatLastConstruction->setEnabled(false); aShowHidden = new QAction(i18n("U&nhide All"), this); actionCollection()->addAction(QStringLiteral("edit_unhide_all"), aShowHidden ); connect(aShowHidden, &QAction::triggered, this, &KigPart::showHidden); aShowHidden->setToolTip(i18n("Show all hidden objects")); aShowHidden->setEnabled( true ); aNewMacro = new QAction(QIcon::fromTheme(QStringLiteral("system-run")), i18n("&New Macro..."), this); actionCollection()->addAction(QStringLiteral("macro_action"), aNewMacro ); connect(aNewMacro, &QAction::triggered, this, &KigPart::newMacro); aNewMacro->setToolTip(i18n("Define a new macro")); aConfigureTypes = new QAction(i18n("Manage &Types..."), this); actionCollection()->addAction(QStringLiteral("types_edit"), aConfigureTypes ); connect(aConfigureTypes, &QAction::triggered, this, &KigPart::editTypes); aConfigureTypes->setToolTip(i18n("Manage macro types.")); aBrowseHistory = new QAction(QIcon::fromTheme(QStringLiteral("view-history")), i18n("&Browse History..."), this); actionCollection()->addAction(QStringLiteral("browse_history"), aBrowseHistory ); connect( aBrowseHistory, &QAction::triggered, this, &KigPart::browseHistory ); aBrowseHistory->setToolTip( i18n( "Browse the history of the current construction." ) ); KigExportManager::instance()->addMenuAction( this, m_widget->realWidget(), actionCollection() ); QAction * a = KStandardAction::zoomIn( m_widget, SLOT(slotZoomIn()), actionCollection() ); a->setToolTip( i18n( "Zoom in on the document" ) ); a->setWhatsThis( i18n( "Zoom in on the document" ) ); a = KStandardAction::zoomOut( m_widget, SLOT(slotZoomOut()), actionCollection() ); a->setToolTip( i18n( "Zoom out of the document" ) ); a->setWhatsThis( i18n( "Zoom out of the document" ) ); a = KStandardAction::fitToPage( m_widget, SLOT(slotRecenterScreen()), actionCollection() ); // grr.. why isn't there an icon for this.. a->setIcon( QIcon( new KIconEngine( "view_fit_to_page", l ) ) ); a->setToolTip( i18n( "Recenter the screen on the document" ) ); a->setWhatsThis( i18n( "Recenter the screen on the document" ) ); a = actionCollection()->addAction(KStandardAction::FullScreen, QStringLiteral("fullscreen"), m_widget, SLOT(toggleFullScreen())); a->setToolTip( i18n( "View this document full-screen." ) ); a->setWhatsThis( i18n( "View this document full-screen." ) ); // TODO: an icon for this.. a = new QAction(QIcon::fromTheme(QStringLiteral("zoom-fit-best")), i18n("&Select Shown Area"), this); actionCollection()->addAction(QStringLiteral("view_select_shown_rect"), a ); connect(a, &QAction::triggered, m_widget, &KigView::zoomRect); 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 QAction(QIcon::fromTheme(QStringLiteral("zoom-original")), i18n("S&elect Zoom Area"), this); actionCollection()->addAction(QStringLiteral("view_zoom_area"), a ); connect(a, &QAction::triggered, m_widget, &KigView::zoomArea); // 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." ) ); aSetCoordinatePrecision = new QAction(i18n("Set Coordinate &Precision..."), this); actionCollection()->addAction(QStringLiteral("settings_set_coordinate_precision"), aSetCoordinatePrecision); aSetCoordinatePrecision->setToolTip( i18n("Set the floating point precision of coordinates in the document. " )); connect(aSetCoordinatePrecision, &QAction::triggered, this, &KigPart::setCoordinatePrecision); aToggleGrid = new KToggleAction(i18n("Show &Grid"), this); actionCollection()->addAction(QStringLiteral("settings_show_grid"), aToggleGrid ); aToggleGrid->setToolTip( i18n( "Show or hide the grid." ) ); aToggleGrid->setChecked( true ); connect( aToggleGrid, &QAction::triggered, this, &KigPart::toggleGrid ); aToggleAxes = new KToggleAction(i18n("Show &Axes"), this); actionCollection()->addAction(QStringLiteral("settings_show_axes"), aToggleAxes ); aToggleAxes->setToolTip( i18n( "Show or hide the axes." ) ); aToggleAxes->setChecked( true ); connect( aToggleAxes, &QAction::triggered, this, &KigPart::toggleAxes ); aToggleNightVision = new KToggleAction(i18n("Wear Infrared Glasses"), this); actionCollection()->addAction(QStringLiteral("settings_toggle_nightvision"), aToggleNightVision ); aToggleNightVision->setToolTip( i18n( "Enable/disable hidden objects' visibility." ) ); aToggleNightVision->setChecked( false ); connect( aToggleNightVision, &QAction::triggered, this, &KigPart::toggleNightVision ); // 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 ); aActions.push_back( ret ); ret->plug( this ); }; } void KigPart::rememberConstruction( ConstructibleAction* ca ) { // mp: // mRememberConstruction holds a pointer to the last construction // done by the user, so that it can be quickly repeated mRememberConstruction = ca; aRepeatLastConstruction->setEnabled(true); aRepeatLastConstruction->setText( i18n( "Repeat Construction (%1)", ca->descriptiveName() ) ); aRepeatLastConstruction->setToolTip( i18n( "Repeat %1 (with new data)", ca->descriptiveName() ) ); } 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( localFilePath() ); 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.", localFilePath() ), i18n( "File Not Found" ) ); return false; }; const QMimeDatabase mimeDb; QMimeType mimeType = mimeDb.mimeTypeForName( arguments().mimeType() ); if ( !mimeType.isValid() ) { // we can always use findByPath instead of findByURL with localFilePath() mimeType = mimeDb.mimeTypeForFile( localFilePath() ); } qDebug() << "mimetype: " << mimeType.name(); 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 open a feature request in KDE's bug tracking system" , mimeType.name()), i18n( "Format Not Supported" ), KMessageBox::Notify | KMessageBox::AllowLink ); return false; }; KigDocument* newdoc = filter->load (localFilePath()); if ( !newdoc ) { closeUrl(); setUrl( QUrl() ); 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 tmp = calcPath( getAllParents( getAllCalcers( document().objects() ) ) ); for ( std::vector::iterator i = tmp.begin(); i != tmp.end(); ++i ) ( *i )->calc( document() ); emit recenterScreen(); redrawScreen(); return true; } bool KigPart::saveFile() { if ( url().isEmpty() ) return internalSaveAs(); // mimetype: const QMimeDatabase mimeDb; const QMimeType mimeType = mimeDb.mimeTypeForFile( localFilePath() ); if ( mimeType.name() != QLatin1String("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" ), KGuiItem( i18n( "Save Kig Format" ) ), KStandardGuiItem::cancel() ) == KMessageBox::No ) return false; + else + { + QFileInfo save( url().toLocalFile() ); + QString extension = save.completeSuffix(); + + if ( extension.isEmpty() ) + { + setUrl( QUrl::fromLocalFile( QString( "%1.kig" ).arg( save.absoluteFilePath() ) ) ); + } + else + { + QString newFileName = save.absoluteFilePath(); + + newFileName.replace( newFileName.lastIndexOf( extension ), extension.length(), QLatin1String( "kig" ) ); + setUrl( QUrl::fromLocalFile( newFileName ) ); + } + } + internalSaveAs(); - }; + } if ( KigFilters::instance()->save( document(), localFilePath() ) ) { setModified ( false ); mhistory->setClean(); return true; } return false; } bool KigPart::queryClose() { if ( KParts::ReadWritePart::queryClose() ) { if ( mode()->eventLoop() != 0 ) { cancelConstruction(); } return true; } return false; } void KigPart::addObject(ObjectHolder* o) { if ( !misGroupingObjects ) mhistory->push( KigCommand::addCommand( *this, o ) ); else { _addObject( o ); mcurrentObjectGroup.push_back( o ); } } void KigPart::addObjects( const std::vector& os ) { if ( !misGroupingObjects ) mhistory->push( KigCommand::addCommand( *this, os ) ); else { _addObjects( os ); mcurrentObjectGroup.insert( mcurrentObjectGroup.end(), os.begin(), os.end() ); } } 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 os; os.push_back( o ); delObjects( os ); } void KigPart::_delObjects( const std::vector& 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& os ) { document().addObjects( os ); setModified( true ); } void KigPart::deleteObjects() { mode()->deleteObjects(); } void KigPart::startObjectGroup() { if ( mcurrentObjectGroup.size() > 0 ) qWarning() << "New object group started while already having objects in object group. Current group will be lost"; mcurrentObjectGroup.clear(); misGroupingObjects = true; } void KigPart::cancelObjectGroup() { misGroupingObjects = false; _delObjects( mcurrentObjectGroup ); mcurrentObjectGroup.clear(); } void KigPart::finishObjectGroup() { misGroupingObjects = false; _delObjects( mcurrentObjectGroup ); addObjects( mcurrentObjectGroup ); mcurrentObjectGroup.clear(); } void KigPart::cancelConstruction() { mode()->cancelConstruction(); } void KigPart::repeatLastConstruction() { if ( mRememberConstruction ) { ConstructibleAction* ca = mRememberConstruction; ca->act( *this ); } } void KigPart::showHidden() { mode()->showHidden(); } void KigPart::newMacro() { mode()->newMacro(); } void KigPart::editTypes() { mode()->editTypes(); } void KigPart::browseHistory() { mode()->browseHistory(); } void KigPart::setHistoryClean( bool clean ) { setModified( !clean ); } void KigPart::setCoordinatePrecision() { KigCoordinatePrecisionDialog dlg(document().isUserSpecifiedCoordinatePrecision(), document().getCoordinatePrecision() ); if( dlg.exec() == QDialog::Accepted ) { int coordinatePrecision = dlg.getUserSpecifiedCoordinatePrecision(); document().setCoordinatePrecision( coordinatePrecision ); } } QUndoStack* KigPart::history() { return mhistory; } void KigPart::delObjects( const std::vector& os ) { if ( os.size() < 1 ) return; std::set delobjs; std::set delcalcers = getAllChildren( getAllCalcers( os ) ); std::map holdermap; std::set curobjs = document().objectsSet(); for ( std::set::iterator i = curobjs.begin(); i != curobjs.end(); ++i ) holdermap[( *i )->calcer()] = *i; for ( std::set::iterator i = delcalcers.begin(); i != delcalcers.end(); ++i ) { std::map::iterator j = holdermap.find( *i ); if ( j != holdermap.end() ) delobjs.insert( j->second ); } assert( delobjs.size() >= os.size() ); std::vector delobjsvect( delobjs.begin(), delobjs.end() ); mhistory->push( KigCommand::removeCommand( *this, delobjsvect ) ); } void KigPart::enableConstructActions( bool enabled ) { for_each( aActions.begin(), aActions.end(), bind2nd( mem_fun( &QAction::setEnabled ), enabled ) ); } void KigPart::unplugActionLists() { unplugActionList( QStringLiteral("user_conic_types") ); unplugActionList( QStringLiteral("user_segment_types") ); unplugActionList( QStringLiteral("user_point_types") ); unplugActionList( QStringLiteral("user_circle_types") ); unplugActionList( QStringLiteral("user_line_types") ); unplugActionList( QStringLiteral("user_other_types") ); unplugActionList( QStringLiteral("user_types") ); } void KigPart::plugActionLists() { plugActionList( QStringLiteral("user_conic_types"), aMNewConic ); plugActionList( QStringLiteral("user_segment_types"), aMNewSegment ); plugActionList( QStringLiteral("user_point_types"), aMNewPoint ); plugActionList( QStringLiteral("user_circle_types"), aMNewCircle ); plugActionList( QStringLiteral("user_line_types"), aMNewLine ); plugActionList( QStringLiteral("user_other_types"), aMNewOther ); plugActionList( QStringLiteral("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 KStandardAction::saveAs action... QString formats = i18n( "Kig Documents (*.kig);;Compressed Kig Documents (*.kigz)" ); QString currentDir = url().toLocalFile(); if ( currentDir.isNull() ) { currentDir = QStandardPaths::writableLocation( QStandardPaths::DocumentsLocation ); } const QString file_name = QFileDialog::getSaveFileName( 0, QString(), currentDir, 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?" , file_name ), i18n( "Overwrite File?" ), KStandardGuiItem::overwrite() ); if ( ret != KMessageBox::Continue ) { return false; } } saveAs( QUrl::fromLocalFile( file_name ) ); return true; } void KigPart::runMode( KigMode* m ) { KigMode* prev = mMode; setMode( m ); QEventLoop e; m->setEventLoop( &e ); e.exec( QEventLoop::AllEvents | QEventLoop::WaitForMoreEvents ); setMode( prev ); redrawScreen(); } void KigPart::doneMode( KigMode* d ) { assert( d == mMode ); if ( d->eventLoop() ) d->eventLoop()->exit(); } void KigPart::actionRemoved( GUIAction* a, GUIUpdateToken& t ) { KigGUIAction* rem = 0; for ( std::vector::iterator i = aActions.begin(); i != aActions.end(); ++i ) { if ( (*i)->guiAction() == a ) { rem = *i; aActions.erase( i ); break; } }; assert( rem ); aMNewSegment.removeAll( rem ); aMNewConic.removeAll( rem ); aMNewPoint.removeAll( rem ); aMNewCircle.removeAll( rem ); aMNewLine.removeAll( rem ); aMNewOther.removeAll( rem ); aMNewAll.removeAll( rem ); t.push_back( rem ); } void KigPart::actionAdded( GUIAction* a, GUIUpdateToken& ) { KigGUIAction* ret = new KigGUIAction( a, *this ); 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: const QStringList dataFiles = getDataFiles( QStringLiteral("kig-types") ); std::vector macros; for ( QStringList::const_iterator file = dataFiles.begin(); file != dataFiles.end(); ++file ) { std::vector 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, &KigPart::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 ).. const QStringList builtinfiles = getDataFiles( QStringLiteral("builtin-macros") ); for ( QStringList::const_iterator file = builtinfiles.begin(); file != builtinfiles.end(); ++file ) { std::vector 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() { QPrinter printer; QPrintPreviewDialog printPreview( &printer ); connect( &printPreview, &QPrintPreviewDialog::paintRequested, [this](QPrinter *p){ doPrint( *p, document().grid(), document().axes() ); }); printPreview.exec(); } void KigPart::filePrint() { QPrinter printer; KigPrintDialogPage* kp = new KigPrintDialogPage(); QPrintDialog printDialog( &printer, m_widget ); printDialog.setWindowTitle( i18n("Print Geometry") ); printDialog.setOptionTabs( { kp } ); printer.setFullPage( true ); //Unsupported in Qt //printer.setPageSelection( QPrinter::ApplicationSide ); kp->setPrintShowGrid( document().grid() ); kp->setPrintShowAxes( document().axes() ); if (printDialog.exec()) { doPrint( printer, kp->printShowGrid(), kp->printShowAxes() ); } } void KigPart::doPrint( QPrinter& printer, bool printGrid, bool printAxes ) { Rect rect = document().suggestedRect(); QRect qrect( 0, 0, printer.width(), printer.height() ); if ( rect.width() * qrect.height() > rect.height() * qrect.width() ) { // qrect is too high.. int nh = static_cast( 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( 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(); painter.drawGrid( document().coordinateSystem(), printGrid, printAxes ); 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& inos ) { std::vector os; for (std::vector::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, i18np( "Hide %1 Object", "Hide %1 Objects", os.size() ) ); for ( std::vector::iterator i = os.begin(); i != os.end(); ++i ) kc->addTask( new ChangeObjectDrawerTask( *i, ( *i )->drawer()->getCopyShown( false ) ) ); mhistory->push( kc ); } void KigPart::showObjects( const std::vector& inos ) { std::vector os; for (std::vector::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, i18np( "Show %1 Object", "Show %1 Objects", os.size() ) ); for ( std::vector::iterator i = os.begin(); i != os.end(); ++i ) kc->addTask( new ChangeObjectDrawerTask( *i, ( *i )->drawer()->getCopyShown( true ) ) ); mhistory->push( kc ); } void KigPart::redrawScreen( KigWidget* w ) { mode()->redrawScreen( w ); } void KigPart::redrawScreen() { for ( std::vector::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" KIGPART_EXPORT int convertToNative( const QUrl &url, const QByteArray& outfile ) { qDebug() << "converting " << url.toDisplayString( QUrl::PrettyDecoded ) << " to " << outfile; if ( ! url.isLocalFile() ) { // TODO qCritical() << "--convert-to-native only supports local files for now."; return -1; } QString file = url.toLocalFile(); QFileInfo fileinfo( file ); if ( ! fileinfo.exists() ) { qCritical() << "The file \"" << file << "\" does not exist"; return -1; }; const QMimeDatabase mimeDb; const QMimeType mimeType = mimeDb.mimeTypeForFile( file ); qDebug() << "mimetype: " << mimeType.name(); KigFilter* filter = KigFilters::instance()->find( mimeType.name() ); if ( !filter ) { qCritical() << "The file \"" << file << "\" is of a filetype not currently supported by Kig."; return -1; }; KigDocument* doc = filter->load (file); if ( !doc ) { qCritical() << "Parse error in file \"" << file << "\"."; return -1; } std::vector tmp = calcPath( getAllParents( getAllCalcers( doc->objects() ) ) ); for ( std::vector::iterator i = tmp.begin(); i != tmp.end(); ++i ) ( *i )->calc( *doc ); for ( std::vector::iterator i = tmp.begin(); i != tmp.end(); ++i ) ( *i )->calc( *doc ); QString out = ( outfile == "-" ) ? QString() : outfile; bool success = KigFilters::instance()->save( *doc, out ); if ( !success ) { qCritical() << "something went wrong while saving"; 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() { const QDir writeableDataLocation ( QStandardPaths::writableLocation( QStandardPaths::DataLocation ) ); const QDir typesDir( writeableDataLocation.absoluteFilePath( QStringLiteral("kig-types") ) ); if ( !typesDir.exists() ) { writeableDataLocation.mkpath( QStringLiteral("kig-types") ); } const QString typesFileWithPath = typesDir.absoluteFilePath( typesFile ); // removing existent types file if ( QFile::exists( typesFileWithPath ) ) QFile::remove( typesFileWithPath ); MacroList* macrolist = MacroList::instance(); macrolist->save( macrolist->macros(), typesFileWithPath ); } void KigPart::loadTypes() { const QDir writeableDataLocation ( QStandardPaths::writableLocation( QStandardPaths::DataLocation ) ); const QDir typesDir( writeableDataLocation.absoluteFilePath( QStringLiteral("kig-types") ) ); if ( typesDir.exists() ) { const QString typesFileWithPath = typesDir.absoluteFilePath( typesFile ); if ( QFile::exists( typesFileWithPath ) ) { std::vector 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(); } #include "kig_part.moc" diff --git a/misc/kigcoordinateprecisiondialog.cpp b/misc/kigcoordinateprecisiondialog.cpp index e5bdae5a..da352dc0 100644 --- a/misc/kigcoordinateprecisiondialog.cpp +++ b/misc/kigcoordinateprecisiondialog.cpp @@ -1,71 +1,75 @@ /** This file is part of Kig, a KDE program for Interactive Geometry... Copyright (C) 2002 Dominique Devriese 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 "kigcoordinateprecisiondialog.h" #include #include +#include #include - #include KigCoordinatePrecisionDialog::KigCoordinatePrecisionDialog(bool isUserSpecified, int currentPrecision ) : QDialog() { ui = new Ui::KigCoordinatePrecisionDialog(); QWidget *mainWidget = new QWidget(this); + QDialogButtonBox *buttonBox = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel ); QVBoxLayout *mainLayout = new QVBoxLayout; setLayout(mainLayout); mainLayout->addWidget(mainWidget); + mainLayout->addWidget( buttonBox ); ui->setupUi(mainWidget); - + ui->m_defaultCheckBox->setCheckState( isUserSpecified ? Qt::Unchecked : Qt::Checked) ; ui->m_precisionLabel->setEnabled( isUserSpecified ); ui->m_precisionSpinBox->setEnabled( isUserSpecified ); ui->m_precisionSpinBox->setValue( currentPrecision ); - + connect(ui->m_defaultCheckBox, &QCheckBox::stateChanged, this, &KigCoordinatePrecisionDialog::toggleCoordinateControls); + connect( buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept ); + connect( buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject ); show(); } KigCoordinatePrecisionDialog::~KigCoordinatePrecisionDialog() { delete ui; } int KigCoordinatePrecisionDialog::getUserSpecifiedCoordinatePrecision() const { if( ui->m_defaultCheckBox->checkState() == Qt::Unchecked ) { return ui->m_precisionSpinBox->value(); } return -1; } void KigCoordinatePrecisionDialog::toggleCoordinateControls( int state ) { bool controlsEnabled = ( state == Qt::Unchecked ); ui->m_precisionLabel->setEnabled( controlsEnabled ); ui->m_precisionSpinBox->setEnabled( controlsEnabled ); } diff --git a/org.kde.kig.appdata.xml b/org.kde.kig.appdata.xml index c609f59e..809d28fd 100644 --- a/org.kde.kig.appdata.xml +++ b/org.kde.kig.appdata.xml @@ -1,129 +1,133 @@ org.kde.kig.desktop CC0-1.0 Kig Kig Kig Kig Kig Kig Kig Kig Kig Kig Kig Kig Kig Kig Kig Kig Kig Kig Kig Kig Kig Kig Kig Kig Kig Kig Kig Kig Kig xxKigxx Kig 數學_Kig Interactive Geometry Interaktivna Geometrija Geometria interactiva Geometria interactiva Interaktivní geometrie Interaktive Geometrie Interactive Geometry Geometría interactiva Interaktiivne geomeetria Vuorovaikutteinen geometria Géométrie interactive Xeometría interactiva Geometri Interaktif Geometria interattiva 인터랙티브 기하학 Interaktyvi geometrija Wesselwarken Geometrie Interactieve meetkunde Interaktiv geometri Interaktywna geometria Geometria Interactiva Geometria interativa Интерактивная геометрия Interaktívna geometria Interaktivna geometrija Interaktiv geometri Etkileşimli Geometri Інтерактивна геометрія xxInteractive Geometryxx 交互几何 交互式幾何作圖

Kig is an interactive mathematics software for learning and teaching geometry. It allows to explore mathematical figures and concepts using the computer and also can serve as a drawing tool for mathematical figures. Constructions can be made with points, vectors, lines, and polygons and all elements can be modified directly by using the mouse. Kig helps teachers and students to make conjectures and to understand how to prove geometric theorems.

Kig je interaktivni matematika softver za učenje i nastavu geometrije. On omogućava da istražite matematičke figure i koncepte koristeći računar i takođe može da posluži kao sredstvo za crtanje za matematičke likovee. Konstrukcije mogu biti napravljeni sa tačkama, vektorima, linijama i poligona i svi elementi mogu izmijeniti pomoću miša. Kig pomaže nastavnicmai i učenici da naprave pretpostavke i da shvate kako se dokazuje geometrijske teoreme.

El Kig és un programari matemàtic interactiu per aprendre i ensenyar geometria. Permet explorar figures matemàtiques i conceptes usant l'ordinador i també pot servir com una eina de dibuix per figures matemàtiques. Les construccions es poden fer amb punts, vectors, línies, i polígons i tots els elements es poden modificar directament usant el ratolí. El Kig ajuda els mestres i els estudiants a fer conjectures i a entendre com demostrar els teoremes geomètrics.

El Kig és un programari matemàtic interactiu per aprendre i ensenyar geometria. Permet explorar figures matemàtiques i conceptes usant l'ordinador i també pot servir com una eina de dibuix per figures matemàtiques. Les construccions es poden fer amb punts, vectors, línies, i polígons i tots els elements es poden modificar directament usant el ratolí. El Kig ajuda els mestres i els estudiants a fer conjectures i a entendre com demostrar els teoremes geomètrics.

Kig ist eine Anwendung für interaktive Mathematik zum Lernen und Lehren. Geometrie. Es ermöglicht die Erforschung mathematischer Elemente und Konzepte mit Hilfe des Rechners und kann auch als Zeichenprogramm für mathematische Abbildungen benutzt werden. Konstruktionen können mit Punkten, Vektoren, Linien und Polygonen und allen anderen Elementen durchgeführt werden. Elemente können direkt mit der Maus verändert werden. Kig hilft Lehrern und Studenten, um Vermutungen anzustellen und zu verstehen, wie man geometrische Beweise erbringen kann. Theoreme.

Kig is an interactive mathematics software for learning and teaching geometry. It allows to explore mathematical figures and concepts using the computer and also can serve as a drawing tool for mathematical figures. Constructions can be made with points, vectors, lines, and polygons and all elements can be modified directly by using the mouse. Kig helps teachers and students to make conjectures and to understand how to prove geometric theorems.

Kig es un software matemático interactivo para el aprendizaje y la enseñanza de la geometría. Permite explorar figuras matemáticas y conceptos usando un equipo informático, además de servir como herramienta de dibujo de figuras matemáticas. Puede realizar construcciones con puntos, vectores, líneas y polígonos, y permite modificar todos estos elementos directamente usando el ratón. Kig ayuda a los profesores y a los estudiantes a hacer conjeturas y a entender cómo probar teoremas geométricos.

Kig on interaktiivne matemaatikatarkvara geomeetria õppimiseks ja õpetamiseks. See võimaldab arvuti vahendusel uurida matemaatilisi kujundeid ja põhimõtteid ning ühtlasi matemaatilisi kujundeid joonistada. Kujundeid võib luua punktide, vektorite, sirgete ja hulknurkade põhjal, kõiki elemente saab muuta otse hiirega. Kig aitab õpetajatele ja õpilastel püstitada hüpoteese ja mõista, kuidas tuleks teoreeme tõestada.

Kig on vuorovaikutteisen geometrian sovellus geometrian opiskeluun ja opetukseen. Sillä voi tutkia matemaattisia kuvioita ja käsitteitä. Sillä voi myös piirtää matemaattisia kuvioita. Muodostelmia voi tehdä pisteistä, vektoreista, suorista, monikulmioista ja kaikki objekteja voi muokata suoraan hiirellä. Kig auttaa opettajia ja opiskelijoita tekemään otaksumia ja ymmärtämään, miten geometrian lauseita todistetaan.

Kig est un logiciel de mathématiques interactif pour enseigner et apprendre la géométrie. Il permet d'explorer des figures géométriques et les concepts mathématiques à l'aide de l'ordinateur et peut également servir d'outil de dessin pour les figures géométriques. Les constructions peuvent être constituées de points, de vecteurs, de droites ou de polygones ; tous les éléments peuvent être modifiés directement avec la souris. Kig aide les enseignants et les étudiants à établir des conjectures et à comprendre comment démontrer les théorèmes de géométrie.

Kig é un programa interactivo de matemáticas para aprender e ensinar xeometría. Permite explorar figuras matemáticas e conceptos usando o computador, e tamén pode empregarse como ferramenta de debuxo de figuras matemáticas. Permite construír figuras mediante puntos, vectores, liñas e polígonos, e todos os elementos poden modificarse directamente usando o rato. Kig axuda aos mestres e estudantes a elaborar conxecturas e a comprender como probar teoremas xeométricos.

Kig adalah perangkat lunak matematika interaktif untuk pembelajaran dan pengajaran geometri. Hal ini memungkinkan untuk mengeksplorasi angka dan konsep matematika menggunakan komputer dan juga dapat berfungsi sebagai alat menggambar untuk angka matematika. Konstruksi dapat dibuat dengan titik, vektor, garis, dan poligon dan semua elemen dapat dimodifikasi secara langsung dengan menggunakan mouse. Kig membantu para guru dan siswa untuk membuat dugaan dan memahami bagaimana membuktikan teorema geometrik.

Kig è un software di matematica interattiva per imparare ed insegnare la geometria. Kig permette di esplorare le figure e i concetti matematici usando il computer, e può anche aiutare a disegnare le figure matematiche. È possibile costruire usando punti, vettori, linee e poligoni, e tutti gli elementi possono essere modificati direttamente con il mouse. Kig aiuta gli insegnanti e gli studenti a fare congetture e a capire come provare teoremi di geometria.

Kig is en wesselwarken Mathematikprogramm för't Lehren vun Geometrie. Du kannst dor mathemaatsch Figuren un Konzepten mit ünnersöken, mat dat lett sik ok as Tekenwarktüüch för mathemaatsch Figuren bruken. Du kannst Dien Konstrukschonen ut Pünkt, Vektoren, Lienen un Veelecken opbuen, un all Elementen laat sik direktemang mit de Muus bewerken. Kig hölpt Schölers un Lehrers bi't Opstellen vun Vermoden, bi't Bewiesen un bi't Verstahn, wodennig een wat bewiesen kann.

Kig is een interactief programma voor het leren en onderwijzen van meetkunde. Wiskundige figuren en ideeën kunnen er mee worden bestudeerd op de computer, en er kunnen wiskundige figuren mee worden getekend. Ook kunnen er constructies mee worden gemaakt met punten, vectoren, lijnstukken, en veelhoeken, en alle elementen kunnen direct met de muis worden gewijzigd. Kig helpt zowel leraren als leerlingen met het opstellen van vermoedens, en het begrip hoe meetkundige stellingen te bewijzen.

Kig jest interaktywnym oprogramowaniem matematycznym do nauki i nauczania geometrii. Umożliwia poznawanie figur matematycznych i pomysłów przy użyciu komputera. Program może także służyć jako narzędzie do rysowania figur matematycznych. Konstrukcje można tworzyć przy użyciu punktów, wektorów, linii oraz wielokątów, a wszystkie elementy można bezpośrednio zmieniać przy użyciu myszy. Kig pomaga nauczycielom i uczniom czynić przypuszczenia i pojąć sposób udowadniania teorii geometrycznych.

O Kig é uma aplicação matemática interactiva para aprender e ensinar geometria. Permite explorar as figuras e conceitos da matemática, usando o computador, e também pode servir como ferramenta de desenho para figuras matemáticas. As construções podem ser feitas com pontos, vectores, linhas e polígonos, podendo todos os elementos ser modificados directamente através do rato. O Kig ajuda os professores e os alunos a tirar conclusões e a compreender como provar teoremas geométricos.

Kig é um aplicativo de matemática interativo para aprender e ensinar geometria. Ele permite explorar as figuras e conceitos da matemática usando o computador e também pode servir como ferramenta de desenho de figuras matemáticas. As construções podem ser feitas com pontos, vetores, linhas e polígonos, onde todos os elementos podem ser modificados diretamente com o mouse. O Kig ajuda os professores e alunos a tirar conclusões e compreender como provar teoremas geométricos.

Kig je interaktívny matematický softvér na výuku geometrie. Umožňuje preskúmať matematické objekty a koncepty pomocou počítača a môže slúžiť aj ako kresliaci nástroj pre matematické objekty. Konštrukcie je možné vytvárať pomocou bodov, vektorov, čiar a polygónov a všetky prvky sa dajú meniť priamo pomocou myši. Kig pomáha učiteľom a študentom vytvoriť dohady a pochopiť, ako dokázať geometrické teorémy.

Kig je interaktivna matematična programska oprema za učenje in poučevanje geometrije. Omogoča raziskovanje matematičnih likov in konceptov s pomočjo računalnika, služi pa tudi kot orodje za risanje likov. Sestavljate lahko točke, vektorje, premice in mnogokotnike, vse predmete pa lahko s pomočjo miške neposredno spremenite. Kig pomaga učiteljem in učencem pri domnevah in pri razumevanju kako rešiti geometrijske teoreme.

Kig är en interaktiv matematisk programvara för att lära sig och lära ut geometri. Det möjliggör utforskning av matematiska figurer och begrepp med datorn, och kan också fungera som ett ritverktyg för matematiska figurer. Konstruktioner kan göras av punkter, vektorer, linjer och polygoner, där alla element kan ändras direkt genom att använda musen. Kig hjälper lärare och elever att dra slutsatser och förstå hur man bevisar geometriska teorem.

Kig, geometriyi öğrenmek ve öğretmek için etkileşimli bir matematik yazılımıdır. Matematiksel şekilleri ve bilgisayarda kullanılan konseptleri keşfetmenize olanak tanır, ayrıca matematiksel şekilleri için bir çizim aracı sağlar. Nokta, vektör, çizgi ve poligonlar ile yapılar yapılabilir ve tüm öğeler fare yardımı ile çizilebilirler. Kig, öğretmen ve öğrencilere bazı varsayımlar yaparak, geometiric teoremlerin nasıl sağlandığını anlatmaya yardımcı olur.

Kig — інтерактивне математичне програмне забезпечення для вивчення і викладання геометрії. За його допомогою можна вивчати математичні фігури та поняття на комп’ютері. Також програма може слугувати для створення креслень до геометричних задач. Побудови можна здійснювати на основі точок, векторів, ліній та багатокутників. Усі побудови можна змінювати безпосередньо за допомогою вказівника миші. Kig допомагає викладачам та учням робити припущення та розбиратися у доведенні теорем геометрії.

xxKig is an interactive mathematics software for learning and teaching geometry. It allows to explore mathematical figures and concepts using the computer and also can serve as a drawing tool for mathematical figures. Constructions can be made with points, vectors, lines, and polygons and all elements can be modified directly by using the mouse. Kig helps teachers and students to make conjectures and to understand how to prove geometric theorems.xx

Kig 是一套互動式的數學軟體,可以學習與教導幾何。它允許您探索數學的圖形與觀念,也有繪圖工具,可以建構點、向量、線、多邊形等,並且所有的元素都可以直接用滑鼠來修改。Kig 可以協助老師與學生學習推論與理解幾何理論。

http://edu.kde.org/kig/ https://bugs.kde.org/enter_bug.cgi?format=guided&product=kig http://docs.kde.org/stable/en/kdeedu/kig/index.html https://www.kde.org/community/donations/?app=kig&source=appdata Interactive geometry with Kig Geometria interactiva amb el Kig Geometria interactiva amb el Kig Interaktivní geometrie s Kig Interaktive Geometrie mit Kig Interactive geometry with Kig Geometría interactiva con Kig Interaktiivne geomeetria Kigis Géométrie interactive à l'aide de Kig Xeometría interactiva con Kig Geometri interaktif dengan Kgig Geometria interattiva con Kig Interactieve meetkunde met Kig Interaktywna geometria z Kig Geometria Interactiva com o Kig Geometria interativa com o Kig Interaktiv geometri med Kig Інтерактивна геометрія у Kig xxInteractive geometry with Kigxx Kig 的交互式几何学 使用 Kig 來交互式幾何作圖 http://kde.org/images/screenshots/kig.png KDE kig + + + +