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

marble

  • sources
  • kde-4.12
  • kdeedu
  • marble
  • src
  • plugins
  • render
  • mapscale
MapScaleFloatItem.cpp
Go to the documentation of this file.
1 //
2 // This file is part of the Marble Virtual Globe.
3 //
4 // This program is free software licensed under the GNU LGPL. You can
5 // find a copy of this license in LICENSE.txt in the top directory of
6 // the source code.
7 //
8 // Copyright 2008 Torsten Rahn <tackat@kde.org>
9 // Copyright 2012 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
10 //
11 
12 #include "MapScaleFloatItem.h"
13 
14 #include <QDebug>
15 #include <QRect>
16 #include <QPixmap>
17 #include <QApplication>
18 #include <QPainter>
19 #include <QPushButton>
20 #include <QMenu>
21 #include <QToolTip>
22 
23 #include "ui_MapScaleConfigWidget.h"
24 #include "MarbleDebug.h"
25 #include "MarbleGlobal.h"
26 #include "projections/AbstractProjection.h"
27 #include "MarbleLocale.h"
28 #include "MarbleModel.h"
29 #include "ViewportParams.h"
30 
31 namespace Marble
32 {
33 
34 MapScaleFloatItem::MapScaleFloatItem()
35  : AbstractFloatItem( 0 ),
36  m_configDialog( 0 ),
37  ui_configWidget( 0 )
38 {
39 }
40 
41 MapScaleFloatItem::MapScaleFloatItem( const MarbleModel *marbleModel )
42  : AbstractFloatItem( marbleModel, QPointF( 10.5, -10.5 ), QSizeF( 0.0, 40.0 ) ),
43  m_configDialog(0),
44  m_radius(0),
45  m_target(QString()),
46  m_leftBarMargin(0),
47  m_rightBarMargin(0),
48  m_scaleBarWidth(0),
49  m_viewportWidth(0),
50  m_scaleBarHeight(5),
51  m_scaleBarDistance(0.0),
52  m_bestDivisor(0),
53  m_pixelInterval(0),
54  m_valueInterval(0),
55  m_scaleInitDone( false ),
56  m_showRatioScale( false ),
57  m_contextMenu( 0 ),
58  m_minimized(false),
59  m_widthScaleFactor(2)
60 {
61 #ifdef Q_WS_MAEMO_5
62  setPosition( QPointF( 220.0, 10.5 ) );
63 #endif // Q_WS_MAEMO_5
64 
65  m_minimizeAction = new QAction(tr("Minimize"), this);
66  m_minimizeAction->setCheckable(true);
67  m_minimizeAction->setChecked(m_minimized);
68  connect(m_minimizeAction, SIGNAL(triggered()), this, SLOT(toggleMinimized()));
69 }
70 
71 MapScaleFloatItem::~MapScaleFloatItem()
72 {
73 }
74 
75 QStringList MapScaleFloatItem::backendTypes() const
76 {
77  return QStringList( "mapscale" );
78 }
79 
80 QString MapScaleFloatItem::name() const
81 {
82  return tr("Scale Bar");
83 }
84 
85 QString MapScaleFloatItem::guiString() const
86 {
87  return tr("&Scale Bar");
88 }
89 
90 QString MapScaleFloatItem::nameId() const
91 {
92  return QString( "scalebar" );
93 }
94 
95 QString MapScaleFloatItem::version() const
96 {
97  return "1.1";
98 }
99 
100 QString MapScaleFloatItem::description() const
101 {
102  return tr("This is a float item that provides a map scale.");
103 }
104 
105 QString MapScaleFloatItem::copyrightYears() const
106 {
107  return "2008, 2010, 2012";
108 }
109 
110 QList<PluginAuthor> MapScaleFloatItem::pluginAuthors() const
111 {
112  return QList<PluginAuthor>()
113  << PluginAuthor( "Torsten Rahn", "tackat@kde.org", tr( "Original Developer" ) )
114  << PluginAuthor( "Khanh-Nhan Nguyen", "khanh.nhan@wpi.edu" )
115  << PluginAuthor( "Illya Kovalevskyy", "illya.kovalevskyy@gmail.com" );
116 }
117 
118 QIcon MapScaleFloatItem::icon () const
119 {
120  return QIcon(":/icons/scalebar.png");
121 }
122 
123 
124 void MapScaleFloatItem::initialize ()
125 {
126 }
127 
128 bool MapScaleFloatItem::isInitialized () const
129 {
130  return true;
131 }
132 
133 void MapScaleFloatItem::changeViewport( ViewportParams *viewport )
134 {
135  int viewportWidth = viewport->width();
136 
137  QString target = marbleModel()->planetId();
138 
139  if ( !( m_radius == viewport->radius()
140  && viewportWidth == m_viewportWidth
141  && m_target == target
142  && m_scaleInitDone ) )
143  {
144  int fontHeight = QFontMetrics( font() ).ascent();
145  if (m_showRatioScale) {
146  setContentSize( QSizeF( viewport->width() / m_widthScaleFactor,
147  fontHeight + 3 + m_scaleBarHeight + fontHeight + 7 ) );
148  } else {
149  setContentSize( QSizeF( viewport->width() / m_widthScaleFactor,
150  fontHeight + 3 + m_scaleBarHeight ) );
151  }
152 
153  m_leftBarMargin = QFontMetrics( font() ).boundingRect( "0" ).width() / 2;
154  m_rightBarMargin = QFontMetrics( font() ).boundingRect( "0000" ).width() / 2;
155 
156  m_scaleBarWidth = contentSize().width() - m_leftBarMargin - m_rightBarMargin;
157  m_viewportWidth = viewport->width();
158  m_radius = viewport->radius();
159  m_scaleInitDone = true;
160 
161  m_pixel2Length = marbleModel()->planetRadius() /
162  (qreal)(viewport->radius());
163 
164  if ( viewport->currentProjection()->surfaceType() == AbstractProjection::Cylindrical )
165  {
166  qreal centerLatitude = viewport->viewLatLonAltBox().center().latitude();
167  // For flat maps we calculate the length of the 90 deg section of the
168  // central latitude circle. For flat maps this distance matches
169  // the pixel based radius propertyy.
170  m_pixel2Length *= M_PI / 2 * cos( centerLatitude );
171  }
172 
173  m_scaleBarDistance = (qreal)(m_scaleBarWidth) * m_pixel2Length;
174 
175  const QLocale::MeasurementSystem measurementSystem = MarbleGlobal::getInstance()->locale()->measurementSystem();
176 
177  if ( measurementSystem == QLocale::ImperialSystem ) {
178  m_scaleBarDistance *= KM2MI;
179  }
180 
181  calcScaleBar();
182 
183  update();
184  }
185 }
186 
187 void MapScaleFloatItem::paintContent( QPainter *painter )
188 {
189  painter->save();
190 
191  painter->setRenderHint( QPainter::Antialiasing, true );
192 
193  int fontHeight = QFontMetrics( font() ).ascent();
194 
195  //calculate scale ratio
196  qreal displayMMPerPixel = 1.0 * painter->device()->widthMM() / painter->device()->width();
197  qreal ratio = m_pixel2Length / (displayMMPerPixel * MM2M);
198 
199  //round ratio to 3 most significant digits, assume that ratio >= 1, otherwise it may display "1 : 0"
200  //i made this assumption because as the primary use case we do not need to zoom in that much
201  qreal power = 1;
202  int iRatio = (int)(ratio + 0.5); //round ratio to the nearest integer
203  while (iRatio >= 1000) {
204  iRatio /= 10;
205  power *= 10;
206  }
207  iRatio *= power;
208  m_ratioString.setNum(iRatio);
209  m_ratioString = m_ratioString = "1 : " + m_ratioString;
210 
211  painter->setPen( QColor( Qt::darkGray ) );
212  painter->setBrush( QColor( Qt::darkGray ) );
213  painter->drawRect( m_leftBarMargin, fontHeight + 3,
214  m_scaleBarWidth,
215  m_scaleBarHeight );
216 
217  painter->setPen( QColor( Qt::black ) );
218  painter->setBrush( QColor( Qt::white ) );
219  painter->drawRect( m_leftBarMargin, fontHeight + 3,
220  m_bestDivisor * m_pixelInterval, m_scaleBarHeight );
221 
222  painter->setPen( QColor( Oxygen::aluminumGray4 ) );
223  painter->drawLine( m_leftBarMargin + 1, fontHeight + 2 + m_scaleBarHeight,
224  m_leftBarMargin + m_bestDivisor * m_pixelInterval - 1, fontHeight + 2 + m_scaleBarHeight );
225  painter->setPen( QColor( Qt::black ) );
226 
227  painter->setBrush( QColor( Qt::black ) );
228 
229  QString intervalStr;
230  int lastStringEnds = 0;
231  int currentStringBegin = 0;
232 
233  for ( int j = 0; j <= m_bestDivisor; j += 2 ) {
234  if ( j < m_bestDivisor ) {
235  painter->drawRect( m_leftBarMargin + j * m_pixelInterval,
236  fontHeight + 3, m_pixelInterval - 1,
237  m_scaleBarHeight );
238 
239  painter->setPen( QColor( Oxygen::aluminumGray5 ) );
240  painter->drawLine( m_leftBarMargin + j * m_pixelInterval + 1, fontHeight + 4,
241  m_leftBarMargin + (j + 1) * m_pixelInterval - 1, fontHeight + 4 );
242  painter->setPen( QColor( Qt::black ) );
243  }
244 
245  QLocale::MeasurementSystem distanceUnit;
246  distanceUnit = MarbleGlobal::getInstance()->locale()->measurementSystem();
247 
248  QString unit = tr("km");
249  switch ( distanceUnit ) {
250  case QLocale::MetricSystem:
251  if ( m_bestDivisor * m_valueInterval > 10000 ) {
252  unit = tr("km");
253  intervalStr.setNum( j * m_valueInterval / 1000 );
254  }
255  else {
256  unit = tr("m");
257  intervalStr.setNum( j * m_valueInterval );
258  }
259  break;
260 
261  case QLocale::ImperialSystem:
262  unit = tr("mi");
263  intervalStr.setNum( j * m_valueInterval / 1000 );
264 
265  if ( m_bestDivisor * m_valueInterval > 3800 ) {
266  intervalStr.setNum( j * m_valueInterval / 1000 );
267  }
268  else {
269  intervalStr.setNum( qreal(j * m_valueInterval ) / 1000.0, 'f', 2 );
270  }
271  break;
272  }
273 
274  painter->setFont( font() );
275 
276  if ( j == 0 ) {
277  painter->drawText( 0, fontHeight, "0 " + unit );
278  lastStringEnds = QFontMetrics( font() ).width( "0 " + unit );
279  continue;
280  }
281 
282  if( j == m_bestDivisor ) {
283  currentStringBegin = ( j * m_pixelInterval
284  - QFontMetrics( font() ).boundingRect( intervalStr ).width() );
285  }
286  else {
287  currentStringBegin = ( j * m_pixelInterval
288  - QFontMetrics( font() ).width( intervalStr ) / 2 );
289  }
290 
291  if ( lastStringEnds < currentStringBegin ) {
292  painter->drawText( currentStringBegin, fontHeight, intervalStr );
293  lastStringEnds = currentStringBegin + QFontMetrics( font() ).width( intervalStr );
294  }
295  }
296 
297  int leftRatioIndent = m_leftBarMargin + (m_scaleBarWidth - QFontMetrics( font() ).width(m_ratioString) ) / 2;
298  painter->drawText( leftRatioIndent, fontHeight + 3 + m_scaleBarHeight + fontHeight + 5, m_ratioString );
299 
300  painter->restore();
301 }
302 
303 void MapScaleFloatItem::calcScaleBar()
304 {
305  qreal magnitude = 1;
306 
307  // First we calculate the exact length of the whole area that is possibly
308  // available to the scalebar in kilometers
309  int magValue = (int)( m_scaleBarDistance );
310 
311  // We calculate the two most significant digits of the km-scalebar-length
312  // and store them in magValue.
313  while ( magValue >= 100 ) {
314  magValue /= 10;
315  magnitude *= 10;
316  }
317 
318  m_bestDivisor = 4;
319  int bestMagValue = 1;
320 
321  for ( int i = 0; i < magValue; i++ ) {
322  // We try to find the lowest divisor between 4 and 8 that
323  // divides magValue without remainder.
324  for ( int j = 4; j < 9; j++ ) {
325  if ( ( magValue - i ) % j == 0 ) {
326  // We store the very first result we find and store
327  // m_bestDivisor and bestMagValue as a final result.
328  m_bestDivisor = j;
329  bestMagValue = magValue - i;
330 
331  // Stop all for loops and end search
332  i = magValue;
333  j = 9;
334  }
335  }
336 
337  // If magValue doesn't divide through values between 4 and 8
338  // (e.g. because it's a prime number) try again with magValue
339  // decreased by i.
340  }
341 
342  m_pixelInterval = (int)( m_scaleBarWidth * (qreal)( bestMagValue )
343  / (qreal)( magValue ) / m_bestDivisor );
344  m_valueInterval = (int)( bestMagValue * magnitude / m_bestDivisor );
345 }
346 
347 QDialog *MapScaleFloatItem::configDialog()
348 {
349  if ( !m_configDialog ) {
350  // Initializing configuration dialog
351  m_configDialog = new QDialog();
352  ui_configWidget = new Ui::MapScaleConfigWidget;
353  ui_configWidget->setupUi( m_configDialog );
354 
355  readSettings();
356 
357  connect( ui_configWidget->m_buttonBox, SIGNAL(accepted()),
358  SLOT(writeSettings()) );
359  connect( ui_configWidget->m_buttonBox, SIGNAL(rejected()),
360  SLOT(readSettings()) );
361 
362  QPushButton *applyButton = ui_configWidget->m_buttonBox->button( QDialogButtonBox::Apply );
363  connect( applyButton, SIGNAL(clicked()) ,
364  this, SLOT(writeSettings()) );
365  }
366  return m_configDialog;
367 }
368 
369 void MapScaleFloatItem::contextMenuEvent( QWidget *w, QContextMenuEvent *e )
370 {
371  if ( !m_contextMenu ) {
372  m_contextMenu = contextMenu();
373 
374  foreach( QAction *action, m_contextMenu->actions() ) {
375  if ( action->text() == tr( "&Configure..." ) ) {
376  m_contextMenu->removeAction( action );
377  break;
378  }
379  }
380 
381  QAction *toggleAction = m_contextMenu->addAction( tr("&Ratio Scale"), this,
382  SLOT(toggleRatioScaleVisibility()) );
383  toggleAction->setCheckable( true );
384  toggleAction->setChecked( m_showRatioScale );
385 
386  m_contextMenu->addAction(m_minimizeAction);
387  }
388 
389  Q_ASSERT( m_contextMenu );
390  m_contextMenu->exec( w->mapToGlobal( e->pos() ) );
391 }
392 
393 void MapScaleFloatItem::toolTipEvent( QHelpEvent *e )
394 {
395  QToolTip::showText( e->globalPos(), m_ratioString );
396 }
397 
398 void MapScaleFloatItem::readSettings()
399 {
400  if ( !m_configDialog )
401  return;
402 
403  if ( m_showRatioScale ) {
404  ui_configWidget->m_showRatioScaleCheckBox->setCheckState( Qt::Checked );
405  } else {
406  ui_configWidget->m_showRatioScaleCheckBox->setCheckState( Qt::Unchecked );
407  }
408 
409  ui_configWidget->m_minimizeCheckBox->setChecked(m_minimized);
410 }
411 
412 void MapScaleFloatItem::writeSettings()
413 {
414  if ( ui_configWidget->m_showRatioScaleCheckBox->checkState() == Qt::Checked ) {
415  m_showRatioScale = true;
416  } else {
417  m_showRatioScale = false;
418  }
419 
420  if (m_minimized != ui_configWidget->m_minimizeCheckBox->isChecked()) {
421  toggleMinimized();
422  }
423 
424  emit settingsChanged( nameId() );
425 }
426 
427 void MapScaleFloatItem::toggleRatioScaleVisibility()
428 {
429  m_showRatioScale = !m_showRatioScale;
430  readSettings();
431  emit settingsChanged( nameId() );
432 }
433 
434 void MapScaleFloatItem::toggleMinimized()
435 {
436  m_minimized = !m_minimized;
437  ui_configWidget->m_minimizeCheckBox->setChecked(m_minimized);
438  m_minimizeAction->setChecked(m_minimized);
439  readSettings();
440  emit settingsChanged( nameId() );
441 
442  if (m_minimized == true) {
443  m_widthScaleFactor = 4;
444  } else {
445  m_widthScaleFactor = 2;
446  }
447 }
448 
449 }
450 
451 Q_EXPORT_PLUGIN2(MapScaleFloatItem, Marble::MapScaleFloatItem)
452 
453 #include "MapScaleFloatItem.moc"
QPainter
Marble::MarbleLocale::measurementSystem
QLocale::MeasurementSystem measurementSystem() const
Definition: MarbleLocale.cpp:45
Marble::MM2M
const qreal MM2M
Definition: MarbleGlobal.h:197
QDialog
Marble::MapScaleFloatItem::nameId
QString nameId() const
Returns the unique name of the plugin.
Definition: MapScaleFloatItem.cpp:90
Marble::MapScaleFloatItem::pluginAuthors
QList< PluginAuthor > pluginAuthors() const
Definition: MapScaleFloatItem.cpp:110
MarbleModel.h
This file contains the headers for MarbleModel.
MapScaleFloatItem.h
Marble::MapScaleFloatItem::backendTypes
QStringList backendTypes() const
Returns the name(s) of the backend that the plugin can render This method should return the name of t...
Definition: MapScaleFloatItem.cpp:75
Marble::MarbleModel::planetId
QString planetId() const
Definition: MarbleModel.cpp:462
QWidget
Marble::PluginAuthor
Definition: PluginInterface.h:28
Marble::FrameGraphicsItem::contentSize
QSizeF contentSize() const
Returns the size of the content of the MarbleGraphicsItem.
Definition: FrameGraphicsItem.cpp:184
Marble::ViewportParams::viewLatLonAltBox
const GeoDataLatLonAltBox & viewLatLonAltBox() const
Definition: ViewportParams.cpp:305
Marble::MapScaleFloatItem::name
QString name() const
Returns the user-visible name of the plugin.
Definition: MapScaleFloatItem.cpp:80
Marble::RenderPlugin::action
QAction * action() const
Plugin's menu action.
Definition: RenderPlugin.cpp:86
Marble::GeoDataCoordinates::latitude
qreal latitude(GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian) const
retrieves the latitude of the GeoDataCoordinates object use the unit parameter to switch between Radi...
Definition: GeoDataCoordinates.cpp:751
Marble::MapScaleFloatItem::copyrightYears
QString copyrightYears() const
Definition: MapScaleFloatItem.cpp:105
MarbleDebug.h
AbstractProjection.h
This file contains the headers for AbstractProjection.
Marble::MapScaleFloatItem::configDialog
QDialog * configDialog()
Returns a pointer to the configuration dialog of the plugin.
Definition: MapScaleFloatItem.cpp:347
Marble::MapScaleFloatItem::guiString
QString guiString() const
String that should be displayed in GUI.
Definition: MapScaleFloatItem.cpp:85
Marble::MapScaleFloatItem::~MapScaleFloatItem
~MapScaleFloatItem()
Definition: MapScaleFloatItem.cpp:71
Marble::ViewportParams::width
int width() const
Definition: ViewportParams.cpp:250
Marble::Oxygen::aluminumGray4
QColor const aluminumGray4
Definition: MarbleColors.h:92
Marble::MapScaleFloatItem::toolTipEvent
virtual void toolTipEvent(QHelpEvent *e)
Definition: MapScaleFloatItem.cpp:393
Marble::RenderPlugin::settingsChanged
void settingsChanged(QString nameId)
This signal is emitted if the settings of the RenderPlugin changed.
Marble::AbstractFloatItem
The abstract class for float item plugins.
Definition: AbstractFloatItem.h:48
Marble::MapScaleFloatItem
The class that creates a map scale.
Definition: MapScaleFloatItem.h:32
Marble::MapScaleFloatItem::version
QString version() const
Definition: MapScaleFloatItem.cpp:95
Marble::MapScaleFloatItem::MapScaleFloatItem
MapScaleFloatItem()
Definition: MapScaleFloatItem.cpp:34
Marble::MarbleGlobal::locale
MarbleLocale * locale() const
Definition: MarbleGlobal.cpp:43
Marble::ViewportParams::currentProjection
const AbstractProjection * currentProjection() const
Definition: ViewportParams.cpp:134
Marble::MapScaleFloatItem::isInitialized
bool isInitialized() const
Definition: MapScaleFloatItem.cpp:128
MarbleLocale.h
MarbleGlobal.h
Marble::ViewportParams
A public class that controls what is visible in the viewport of a Marble map.
Definition: ViewportParams.h:44
Marble::MapScaleFloatItem::initialize
void initialize()
Definition: MapScaleFloatItem.cpp:124
Q_EXPORT_PLUGIN2
#define Q_EXPORT_PLUGIN2(a, b)
Definition: marble_export.h:34
Marble::KM2MI
const qreal KM2MI
Definition: MarbleGlobal.h:189
Marble::GeoDataLatLonAltBox::center
virtual GeoDataCoordinates center() const
returns the center of this box
Definition: GeoDataLatLonAltBox.cpp:152
ViewportParams.h
This file contains the headers for ViewportParams.
Marble::MarbleGlobal::getInstance
static MarbleGlobal * getInstance()
Definition: MarbleGlobal.cpp:37
Marble::AbstractProjection::Cylindrical
Definition: AbstractProjection.h:54
Marble::MarbleModel
The data model (not based on QAbstractModel) for a MarbleWidget.
Definition: MarbleModel.h:96
Marble::Oxygen::aluminumGray5
QColor const aluminumGray5
Definition: MarbleColors.h:91
Marble::MapScaleFloatItem::contextMenuEvent
virtual void contextMenuEvent(QWidget *w, QContextMenuEvent *e)
Definition: MapScaleFloatItem.cpp:369
Marble::ViewportParams::radius
int radius() const
Definition: ViewportParams.cpp:195
Marble::MapScaleFloatItem::description
QString description() const
Returns a user description of the plugin.
Definition: MapScaleFloatItem.cpp:100
Marble::ScreenGraphicsItem::setPosition
void setPosition(const QPointF &position)
Set the position of the ScreenGraphicsItem.
Definition: ScreenGraphicsItem.cpp:44
Marble::MarbleModel::planetRadius
qreal planetRadius() const
Definition: MarbleModel.cpp:452
M_PI
#define M_PI
Definition: GeoDataCoordinates.h:26
Marble::MarbleGraphicsItem::update
void update()
Marks the item and all parent items as invalid.
Definition: MarbleGraphicsItem.cpp:167
Marble::MapScaleFloatItem::changeViewport
void changeViewport(ViewportParams *viewport)
Definition: MapScaleFloatItem.cpp:133
Marble::AbstractFloatItem::font
QFont font() const
current font for rendering
Definition: AbstractFloatItem.cpp:107
Marble::MapScaleFloatItem::paintContent
void paintContent(QPainter *painter)
Here the items paint their content.
Definition: MapScaleFloatItem.cpp:187
Marble::RenderPlugin::marbleModel
const MarbleModel * marbleModel() const
Access to the MarbleModel.
Definition: RenderPlugin.cpp:81
Marble::FrameGraphicsItem::setContentSize
void setContentSize(const QSizeF &size)
Sets the size of the content of the item.
Definition: FrameGraphicsItem.cpp:204
Marble::MapScaleFloatItem::icon
QIcon icon() const
Returns an icon for the plugin.
Definition: MapScaleFloatItem.cpp:118
Marble::AbstractFloatItem::contextMenu
QMenu * contextMenu()
Definition: AbstractFloatItem.cpp:230
Marble::AbstractProjection::surfaceType
virtual SurfaceType surfaceType() const =0
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:38:51 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

marble

Skip menu "marble"
  • 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