• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeedu API Reference
  • KDE Home
  • Contact Us
 

parley

  • sources
  • kde-4.12
  • kdeedu
  • parley
  • src
parleydocument.cpp
Go to the documentation of this file.
1 /***************************************************************************
2 
3  Copyright 2007-2008 Frederik Gladhorn <frederik.gladhorn@kdemail.net>
4 
5  ***************************************************************************/
6 
7 /***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "parleydocument.h"
17 
18 #include "../config-parley.h"
19 #include "parleymainwindow.h"
20 #include "editor/editor.h"
21 #include "version.h"
22 #include "prefs.h"
23 
24 #include "vocabulary/vocabularyview.h"
25 #include "settings/documentproperties.h"
26 #include "welcomescreen/welcomescreen.h"
27 
28 #include <keduvoclesson.h>
29 #include <keduvocleitnerbox.h>
30 #include <keduvocexpression.h>
31 #include <keduvocwordtype.h>
32 
33 #include <KFileDialog>
34 #include <KRecentFilesAction>
35 #include <KStandardDirs>
36 #include <knewstuff3/downloaddialog.h>
37 #include <knewstuff3/uploaddialog.h>
38 #include <KEMailSettings>
39 #include <KMessageBox>
40 #include <KProcess>
41 #include <KTempDir>
42 
43 #include <QTimer>
44 #include <QtGui/QPrinter>
45 #include <QtGui/QPrintDialog>
46 
47 #ifdef HAVE_LIBXSLT
48 #include "export/exportdialog.h"
49 #include <libxml/parser.h>
50 #include <libxml/tree.h>
51 #include <libxslt/xslt.h>
52 #include <libxslt/xsltInternals.h>
53 #include <libxslt/transform.h>
54 #include <libxslt/xsltutils.h>
55 #endif
56 
57 #include "settings/languageproperties.h"
58 #include "settings/documentproperties.h"
59 
60 namespace DocumentHelper {
61 void fetchGrammar(KEduVocDocument* doc, int languageIndex)
62 {
63  QString locale = doc->identifier(languageIndex).locale();
64 
65  KUrl location(QString("http://edu.kde.org/parley/locale/") + locale + QString(".kvtml"));
66 
67  KEduVocDocument grammarDoc;
68  if (grammarDoc.open(location) == KEduVocDocument::NoError) {
69  doc->identifier(languageIndex).setArticle(grammarDoc.identifier(0).article());
70  doc->identifier(languageIndex).setPersonalPronouns(grammarDoc.identifier(0).personalPronouns());
71  // @todo m_doc->identifier(index).setDeclension(grammarDoc.identifier(0).declension());
72  doc->identifier(languageIndex).setTenseList(grammarDoc.identifier(0).tenseList());
73  } else {
74  kDebug() << "Download of " << location.url() << " failed.";
75  }
76 }
77 } // namespace DocumentHelper
78 
79 ParleyDocument::ParleyDocument(ParleyMainWindow* parleyMainWindow)
80  : QObject(parleyMainWindow)
81  , m_parleyApp(parleyMainWindow)
82  , m_doc(new KEduVocDocument(this))
83  , m_backupTimer(0)
84 {
85 }
86 
87 ParleyDocument::~ParleyDocument()
88 {
89  delete m_backupTimer;
90  delete m_doc;
91 }
92 
93 KEduVocDocument * ParleyDocument::document()
94 {
95  return m_doc;
96 }
97 
98 void ParleyDocument::setTitle(const QString& title)
99 {
100  m_doc->setTitle(title);
101  m_parleyApp->slotUpdateWindowCaption();
102  m_doc->setModified(true);
103 }
104 
105 void ParleyDocument::slotFileNew()
106 {
107  if (m_parleyApp->queryExit()) {
108  newDocument(true);
109  }
110 }
111 
112 void ParleyDocument::newDocument(bool wizard)
113 {
114  KEduVocDocument *newDoc = new KEduVocDocument();
115 
116  initializeDefaultGrammar(newDoc);
117  setDefaultDocumentProperties(newDoc);
118  bool showGrammarDialog = false;
119  bool fetchGrammarOnline = false;
120  if (wizard) {
121  DocumentProperties* titleAuthorWidget = new DocumentProperties(newDoc, true, m_parleyApp);
122  KDialog* titleAuthorDialog;
123  titleAuthorDialog = new KDialog(m_parleyApp);
124  titleAuthorDialog->setMainWidget( titleAuthorWidget );
125  titleAuthorDialog->setCaption(i18nc("@title:window document properties", "Properties for %1", newDoc->url().url()));
126  connect(titleAuthorDialog, SIGNAL(accepted()), titleAuthorWidget, SLOT(accept()));
127  if(titleAuthorDialog->exec()) {
128  showGrammarDialog = titleAuthorWidget->grammarCheckBox->isChecked();
129  fetchGrammarOnline = titleAuthorWidget->downloadGrammarCheckBox->isChecked();
130  delete titleAuthorDialog;
131  } else {
132  delete titleAuthorDialog;
133  delete newDoc;
134  return;
135  }
136  }
137 
138  close();
139  m_doc = newDoc;
140 
141  emit documentChanged(m_doc);
142  enableAutoBackup(Prefs::autoBackup());
143 
144 
145  if(fetchGrammarOnline) {
146  DocumentHelper::fetchGrammar(m_doc, 0);
147  DocumentHelper::fetchGrammar(m_doc, 1);
148  }
149  if(showGrammarDialog) {
150  languageProperties();
151  }
152 
153  m_parleyApp->showEditor();
154 }
155 
156 void ParleyDocument::slotFileOpen()
157 {
158  if (m_parleyApp->queryExit()) {
159  QCheckBox *practiceCheckBox = new QCheckBox(i18n("Open in practice &mode"));
160  practiceCheckBox->setChecked(m_parleyApp->currentComponent() != ParleyMainWindow::EditorComponent);
161  KFileDialog dialog(QString(), KEduVocDocument::pattern(KEduVocDocument::Reading), m_parleyApp, practiceCheckBox);
162  dialog.setCaption(i18n("Open Vocabulary Collection"));
163  if(dialog.exec() && !dialog.selectedUrl().isEmpty()) {
164  open(dialog.selectedUrl());
165  if(practiceCheckBox->isChecked()) {
166  m_parleyApp->showPracticeConfiguration();
167  } else {
168  m_parleyApp->showEditor();
169  }
170  }
171  }
172 }
173 
174 void ParleyDocument::slotFileOpenRecent(const KUrl& url)
175 {
176  if (m_parleyApp->queryExit()) {
177  open(url);
178  m_parleyApp->showEditor();
179  }
180 }
181 
182 bool ParleyDocument::open(const KUrl & url)
183 {
184  if (url.path().isEmpty()) {
185  return false;
186  }
187 
188  close();
189  m_doc = new KEduVocDocument(this);
190  m_doc->setCsvDelimiter(Prefs::separator());
191  int ret = m_doc->open(url);
192  if (ret != KEduVocDocument::NoError) {
193  KMessageBox::error(
194  m_parleyApp, i18n("Could not read collection from \"%1\"", url.url()), i18nc("@title:window", "Open Collection"));
195  delete m_doc;
196  m_doc = 0;
197  return false;
198  }
199 
200  //m_parleyApp->editor()->updateDocument();
201  m_parleyApp->addRecentFile(url, m_doc->title());
202 
203  emit documentChanged(m_doc);
204  enableAutoBackup(Prefs::autoBackup());
205 
206  return true;
207 }
208 
209 void ParleyDocument::close()
210 {
211  kDebug() << "Close Document";
212  enableAutoBackup(false);
213  emit documentChanged(0);
214  disconnect(m_doc);
215  delete m_doc;
216  m_doc = 0;
217  m_parleyApp->slotUpdateWindowCaption();
218 }
219 
220 void ParleyDocument::openGHNS()
221 {
222  if (m_parleyApp->queryExit()) {
223  QString downloadDir = KStandardDirs::locateLocal("data", "kvtml/");
224  KUrl url = KFileDialog::getOpenUrl(
225  downloadDir,
226  KEduVocDocument::pattern(KEduVocDocument::Reading),
227  m_parleyApp,
228  i18n("Open Downloaded Vocabulary Collection"));
229  if ( open(url) ) {
230  m_parleyApp->showPracticeConfiguration();
231  }
232  }
233 }
234 
235 void ParleyDocument::save()
236 {
237  if (m_doc->url().fileName() == i18n("Untitled")) {
238  saveAs();
239  return;
240  }
241 
242  // remove previous backup
243  QFile::remove(m_doc->url().toLocalFile()+'~');
244  ::rename(QFile::encodeName(m_doc->url().toLocalFile()), QFile::encodeName(m_doc->url().toLocalFile()+'~'));
245 
246  m_doc->setCsvDelimiter(Prefs::separator());
247 
248  emit statesNeedSaving();
249 
250  int result = m_doc->saveAs(m_doc->url(), KEduVocDocument::Automatic, QString::fromLatin1("Parley ") + PARLEY_VERSION_STRING);
251  if ( result != 0 ) {
252  KMessageBox::error(m_parleyApp,
253  i18n("Writing file \"%1\" resulted in an error: %2", m_doc->url().url(),
254  m_doc->errorDescription(result)), i18nc("@title:window", "Save File"));
255  saveAs();
256  return;
257  }
258  m_parleyApp->addRecentFile(m_doc->url(), m_doc->title());
259  enableAutoBackup(Prefs::autoBackup());
260 }
261 
262 void ParleyDocument::saveAs(KUrl url)
263 {
264  if (!m_doc) {
265  return;
266  }
267 
268  if (url.isEmpty()) {
269  url = KFileDialog::getSaveUrl(QString(),
270  KEduVocDocument::pattern(KEduVocDocument::Writing),
271  m_parleyApp->parentWidget(),
272  i18n("Save Vocabulary As"));
273  }
274  if (url.isEmpty()) {
275  return;
276  }
277 
278  QFileInfo fileinfo(url.toLocalFile());
279  if (fileinfo.exists()) {
280  if(KMessageBox::warningContinueCancel(0,
281  i18n("<qt>The file<p><b>%1</b></p>already exists. Do you want to overwrite it?</qt>",
282  url.toLocalFile()),QString(),KStandardGuiItem::overwrite()) == KMessageBox::Cancel) {
283  return;
284  }
285  }
286 
287  QString msg = i18nc("@info:status saving a file", "Saving %1", url.toLocalFile());
288 
289  QFile::remove(url.toLocalFile()+'~'); // remove previous backup
290  QFile::rename(QFile::encodeName(url.toLocalFile()), QFile::encodeName(QString(url.toLocalFile()+'~')));
291 
292  m_doc->setCsvDelimiter(Prefs::separator());
293 
294  if ( !url.fileName().contains('.') ) {
295  url.setFileName(url.fileName() + QString::fromLatin1(".kvtml"));
296  }
297 
298  int result = m_doc->saveAs(url, KEduVocDocument::Automatic, "Parley");
299  if (result == 0) {
300  m_parleyApp->addRecentFile(m_doc->url(), m_doc->title());
301  emit statesNeedSaving();
302  } else {
303  KMessageBox::error(m_parleyApp, i18n("Writing file \"%1\" resulted in an error: %2",
304  m_doc->url().url(), m_doc->errorDescription(result)), i18nc("@title:window", "Save File"));
305  }
306 }
307 
308 void ParleyDocument::initializeDefaultGrammar(KEduVocDocument *doc)
309 {
310  KEduVocWordType *root = doc->wordTypeContainer();
311  KEduVocWordType *noun = new KEduVocWordType(i18n("Noun"), root);
312  noun->setWordType(KEduVocWordFlag::Noun);
313  root->appendChildContainer(noun);
314 
315  KEduVocWordType *nounChild = new KEduVocWordType(i18n("Masculine"), noun);
316  nounChild->setWordType(KEduVocWordFlag::Noun | KEduVocWordFlag::Masculine);
317  noun->appendChildContainer(nounChild);
318  nounChild = new KEduVocWordType(i18n("Feminine"), noun);
319  nounChild->setWordType(KEduVocWordFlag::Noun | KEduVocWordFlag::Feminine);
320  noun->appendChildContainer(nounChild);
321  nounChild = new KEduVocWordType(i18n("Neuter"), noun);
322  nounChild->setWordType(KEduVocWordFlag::Noun | KEduVocWordFlag::Neuter);
323  noun->appendChildContainer(nounChild);
324 
325  KEduVocWordType *verb = new KEduVocWordType(i18n("Verb"), root);
326  verb->setWordType(KEduVocWordFlag::Verb);
327  root->appendChildContainer(verb);
328 
329  KEduVocWordType *adjective = new KEduVocWordType(i18n("Adjective"), root);
330  adjective->setWordType(KEduVocWordFlag::Adjective);
331  root->appendChildContainer(adjective);
332 
333  KEduVocWordType *adverb = new KEduVocWordType(i18n("Adverb"), root);
334  adverb->setWordType(KEduVocWordFlag::Adverb);
335  root->appendChildContainer(adverb);
336 
337  KEduVocWordType *conjunction = new KEduVocWordType(i18n("Conjunction"), root);
338  conjunction->setWordType(KEduVocWordFlag::Conjunction);
339  root->appendChildContainer(conjunction);
340 }
341 
342 
343 void ParleyDocument::setDefaultDocumentProperties(KEduVocDocument *doc)
344 {
345  KEMailSettings emailSettings;
346  emailSettings.setProfile(emailSettings.defaultProfileName());
347  doc->setAuthor(emailSettings.getSetting(KEMailSettings::RealName));
348  doc->setAuthorContact(emailSettings.getSetting(KEMailSettings::EmailAddress));
349 
350  doc->setLicense( i18n("Public Domain") );
351  doc->setCategory( i18n("Languages") );
352 
353  QString locale = KGlobal::locale()->language();
354 
355  doc->appendIdentifier();
356  doc->appendIdentifier();
357  doc->identifier(0).setName( KGlobal::locale()->languageCodeToName( locale) );
358  doc->identifier(0).setLocale( locale );
359  doc->identifier(1).setName( i18n("A Second Language") );
360  doc->identifier(1).setLocale( locale );
361 
362  KEduVocLesson* lesson = new KEduVocLesson(i18n("Lesson 1"), doc->lesson());
363  doc->lesson()->appendChildContainer(lesson);
364 
365  // add some entries
366  for ( int i = 0; i < 15 ; i++ ) {
367  lesson->appendEntry(new KEduVocExpression());
368  }
369 
370  doc->setModified(false);
371 }
372 
373 void ParleyDocument::slotGHNS()
374 {
375  QString fileName;
376  KNS3::DownloadDialog newStuffDialog(ParleyMainWindow::instance());
377  newStuffDialog.exec();
378  KNS3::Entry::List entries = newStuffDialog.installedEntries();
379  int numberInstalled = entries.size();
380  foreach(const KNS3::Entry& entry, entries) {
381  // check mime type and if kvtml, open it
382  foreach(const QString &file, entry.installedFiles()) {
383  KMimeType::Ptr mimeType = KMimeType::findByPath(file);
384  kDebug() << "KNS2 file of mime type:" << KMimeType::findByPath(file)->name();
385  if (mimeType->is("application/x-kvtml")) {
386  ParleyMainWindow::instance()->addRecentFile(file, QString());
387  fileName = file;
388  }
389  }
390  }
391 
392  // to enable the display in the welcome screen
393  Prefs::self()->writeConfig();
394  m_parleyApp->updateRecentFilesModel();
395  if (numberInstalled > 1) {
396  openGHNS();
397  } else if (numberInstalled == 1) {
398  if (open(KUrl(fileName)))
399  m_parleyApp->showPracticeConfiguration();
400  else
401  KMessageBox::error(m_parleyApp, i18n("Could not open vocabulary collection \"%1\"", entries.first().name()));
402  }
403 }
404 
405 void ParleyDocument::documentProperties()
406 {
407  DocumentProperties* titleAuthorWidget = new DocumentProperties(m_doc, false, m_parleyApp);
408  KDialog* titleAuthorDialog;
409  titleAuthorDialog = new KDialog(m_parleyApp);
410  titleAuthorDialog->setMainWidget( titleAuthorWidget );
411 
412  // the language options are only shown, when this is used to create a new document.
413  titleAuthorWidget->languageGroupBox->setVisible(false);
414  titleAuthorDialog->setCaption(i18nc("@title:window document properties", "Properties for %1", m_doc->url().url()));
415  connect(titleAuthorDialog, SIGNAL(accepted()), titleAuthorWidget, SLOT(accept()));
416  titleAuthorDialog->exec();
417  delete titleAuthorDialog;
418 }
419 
420 void ParleyDocument::languageProperties()
421 {
422  LanguageProperties properties(m_doc, m_parleyApp);
423  if ( properties.exec() == KDialog::Accepted ) {
424  emit languagesChanged();
425  }
426 }
427 
428 void ParleyDocument::uploadFile()
429 {
430  // save file to temp location
431  KTempDir dir;
432  KUrl url(dir.name() + m_doc->url().fileName());
433  kDebug() << "save in " << url.url();
434  m_doc->saveAs(url, KEduVocDocument::Automatic, "Parley");
435 
436  KEduVocDocument tempDoc(this);
437  tempDoc.open(url);
438  // remove grades
439  tempDoc.lesson()->resetGrades(-1, KEduVocContainer::Recursive);
440  tempDoc.saveAs(url, KEduVocDocument::Automatic, "Parley");
441 
442  // upload
443  KNS3::UploadDialog dialog(ParleyMainWindow::instance());
444  dialog.setUploadFile(url);
445  dialog.exec();
446 }
447 
448 void ParleyDocument::exportDialog()
449 {
450 #ifdef HAVE_LIBXSLT
451  ExportDialog dialog(this, m_parleyApp);
452  dialog.exec();
453 #endif
454 }
455 
456 void ParleyDocument::slotFileMerge()
457 {
459 // KUrl url = KFileDialog::getOpenUrl(QString(), KEduVocDocument::pattern(KEduVocDocument::Reading), parentWidget(), i18n("Merge Vocabulary File"));
460  //
461 // if (!url.isEmpty()) {
462 // QString msg = i18n("Loading %1", url.path());
463 // slotStatusMsg(msg);
464  //
465 // KEduVocDocument *new_doc = new KEduVocDocument(this);
466 // new_doc->setCsvDelimiter(Prefs::separator());
467 // new_doc->open(url);
468  //
469 // m_doc->merge(new_doc, true);
470  //
471 // KEduVocWordFlag::setTenseNames(m_doc->tenseDescriptions());
472 // KVTUsage::setUsageNames(m_doc->usageDescriptions());
473  //
474 // delete(new_doc);
475 // m_recentFilesAction->addUrl(url);
476 // m_tableModel->reset();
477 // m_lessonModel->setDocument(m_doc);
478 // m_tableView->adjustContent();
479 // }
480 }
481 
482 void ParleyDocument::enableAutoBackup(bool enable)
483 {
484  if ( !enable ) {
485  if ( m_backupTimer ) {
486  m_backupTimer->stop();
487  }
488  } else {
489  if ( !m_backupTimer ) {
490  m_backupTimer = new QTimer(this);
491  connect(m_backupTimer, SIGNAL(timeout()), this, SLOT(save()));
492  }
493  m_backupTimer->start(Prefs::backupTime() * 60 * 1000);
494  }
495 }
496 
497 #include "parleydocument.moc"
ParleyDocument::ParleyDocument
ParleyDocument(ParleyMainWindow *parleyMainWindow)
Definition: parleydocument.cpp:79
ParleyMainWindow::currentComponent
Component currentComponent()
Definition: parleymainwindow.cpp:417
ParleyDocument::documentChanged
void documentChanged(KEduVocDocument *newDocument)
PARLEY_VERSION_STRING
#define PARLEY_VERSION_STRING
Definition: version.h:3
ParleyDocument::statesNeedSaving
void statesNeedSaving()
ParleyDocument::languageProperties
void languageProperties()
Definition: parleydocument.cpp:420
ParleyDocument::setTitle
void setTitle(const QString &title)
Definition: parleydocument.cpp:98
ParleyMainWindow::showEditor
void showEditor()
Definition: parleymainwindow.cpp:266
ParleyDocument::documentProperties
void documentProperties()
General doc properties like title, author etc.
Definition: parleydocument.cpp:405
ParleyDocument::slotFileMerge
void slotFileMerge()
merge a document
Definition: parleydocument.cpp:456
ParleyDocument::exportDialog
void exportDialog()
Definition: parleydocument.cpp:448
ParleyMainWindow
Definition: parleymainwindow.h:68
DocumentHelper::fetchGrammar
void fetchGrammar(KEduVocDocument *doc, int languageIndex)
Definition: parleydocument.cpp:61
ParleyDocument::slotFileOpenRecent
void slotFileOpenRecent(const KUrl &url)
opens a file from the recent files menu
Definition: parleydocument.cpp:174
ParleyDocument::document
KEduVocDocument * document()
Definition: parleydocument.cpp:93
KDialog
prefs.h
ParleyDocument::slotFileOpen
void slotFileOpen()
open a document
Definition: parleydocument.cpp:156
welcomescreen.h
QObject
editor.h
Prefs::self
static Prefs * self()
Definition: prefs.cpp:17
ParleyDocument::save
void save()
save a document
Definition: parleydocument.cpp:235
ParleyMainWindow::EditorComponent
Definition: parleymainwindow.h:81
parleydocument.h
ParleyDocument::newDocument
void newDocument(bool wizard)
Definition: parleydocument.cpp:112
exportdialog.h
ParleyMainWindow::instance
static ParleyMainWindow * instance()
Definition: parleymainwindow.cpp:56
ParleyMainWindow::queryExit
bool queryExit()
overloaded for Message box on last window exit
Definition: parleymainwindow.cpp:192
ParleyMainWindow::showPracticeConfiguration
void showPracticeConfiguration()
Definition: parleymainwindow.cpp:271
LanguageProperties
Definition: languageproperties.h:22
ExportDialog
Definition: exportdialog.h:24
ParleyDocument::enableAutoBackup
void enableAutoBackup(bool enable)
Definition: parleydocument.cpp:482
documentproperties.h
languageproperties.h
ParleyDocument::openGHNS
void openGHNS()
open a downloaded (knewstuff/get hot new stuff) document
Definition: parleydocument.cpp:220
version.h
ParleyDocument::~ParleyDocument
~ParleyDocument()
Definition: parleydocument.cpp:87
ParleyDocument::uploadFile
void uploadFile()
upload the current file
Definition: parleydocument.cpp:428
parleymainwindow.h
Prefs::backupTime
static int backupTime()
Get Time interval between two automatic backups.
Definition: prefs.h:217
ParleyDocument::slotGHNS
void slotGHNS()
download new vocabularies
Definition: parleydocument.cpp:373
ParleyMainWindow::updateRecentFilesModel
void updateRecentFilesModel()
update the list of recent files in the welcome screen
Definition: parleymainwindow.cpp:122
DocumentProperties
Definition: documentproperties.h:33
Prefs::autoBackup
static bool autoBackup()
Get If true, a backup is saved every BackupTime minutes.
Definition: prefs.h:198
ParleyMainWindow::addRecentFile
void addRecentFile(const KUrl &url, const QString &name)
add a new entry to the list of recent files
Definition: parleymainwindow.cpp:116
ParleyDocument::open
bool open(const KUrl &)
Opens the given url, displays an error message and returns false on failure.
Definition: parleydocument.cpp:182
ParleyDocument::close
void close()
Definition: parleydocument.cpp:209
ParleyDocument::saveAs
void saveAs(KUrl file=KUrl())
Definition: parleydocument.cpp:262
ParleyDocument::slotFileNew
void slotFileNew()
open a new application window
Definition: parleydocument.cpp:105
vocabularyview.h
ParleyMainWindow::slotUpdateWindowCaption
void slotUpdateWindowCaption()
Update the title bar of the main window with the current document.
Definition: parleymainwindow.cpp:132
Prefs::separator
static QString separator()
Get This sets the separator used when copying/pasting text, default is Tab.
Definition: prefs.h:103
ParleyDocument::languagesChanged
void languagesChanged()
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:42:06 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

parley

Skip menu "parley"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • kstars
  • libkdeedu
  •   keduvocdocument
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal