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

parley

  • sources
  • kde-4.14
  • kdeedu
  • parley
  • src
  • dashboard
dashboard.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  Copyright 2014 Inge Wallin <inge@lysator.liu.se>
3  ***************************************************************************/
4 
5 /***************************************************************************
6  * *
7  * This program is free software; you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation; either version 2 of the License, or *
10  * (at your option) any later version. *
11  * *
12  ***************************************************************************/
13 
14 #include <Qt>
15 #include <QtGui>
16 #include <QTimer>
17 #include <QTime>
18 #include <QDebug>
19 #include <QSignalMapper>
20 #include <QStandardItemModel>
21 
22 #include <KMimeType>
23 #include <KDebug>
24 #include <KAction>
25 #include <KActionCollection>
26 
27 #include "../utils.h"
28 #include "dashboard.h"
29 #include "buttondelegate.h"
30 #include "parleymainwindow.h"
31 #include "parleydocument.h"
32 #include "practice/themedbackgroundrenderer.h"
33 #include "practice/imagewidget.h"
34 #include "statistics/statisticsmainwindow.h"
35 #include "statistics/statisticsmodel.h"
36 
37 #include "collection.h"
38 #include "collectionwidget.h"
39 #include "gradereferencewidget.h"
40 
41 
42 // ----------------------------------------------------------------
43 
44 
45 static int randInt(int low, int high)
46 {
47  // Random number between low and high
48  return qrand() % ((high + 1) - low) + low;
49 }
50 
51 
52 // ================================================================
53 // class Dashboard
54 
55 
56 int ROWSIZE = 4; // Number of collection widgets (+ 1 initial spacerItem) per row
57 
58 
59 Dashboard::Dashboard(ParleyMainWindow *parent)
60  : KXmlGuiWindow(parent)
61  , m_mainWindow(parent)
62 {
63  // KXmlGui
64  setXMLFile("dashboardui.rc");
65  setObjectName("Dashboard");
66 
67  m_widget = new Practice::ImageWidget(this);
68  m_widget->setScalingEnabled(false, false);
69  m_widget->setKeepAspectRatio(Qt::IgnoreAspectRatio);
70  m_widget->setFadingEnabled(false);
71 
72  m_ui = new Ui::Dashboard();
73  m_ui->setupUi(m_widget);
74  setCentralWidget(m_widget);
75  m_practiceSignalMapper = new QSignalMapper(this);
76  m_removeSignalMapper = new QSignalMapper(this);
77 
78  QTime time = QTime::currentTime();
79  qsrand((uint)time.msec());
80 
81  QFont font = m_ui->recentLabel->font();
82  font.setBold(true);
83  m_ui->recentLabel->setFont(font);
84  font = m_ui->completedLabel->font();
85  font.setBold(true);
86  m_ui->completedLabel->setFont(font);
87 
88  m_ui->newButton->setIcon(KIcon("document-new"));
89  m_ui->openButton->setIcon(KIcon("document-open"));
90  m_ui->ghnsButton->setIcon(KIcon("get-hot-new-stuff"));
91  GradeReferenceWidget *gradeReferenceWidget = new GradeReferenceWidget();
92  gradeReferenceWidget->setMinimumSize(m_widget->width(), 50);
93  m_ui->gridLayout->addWidget(gradeReferenceWidget, 1, 0, 1, ROWSIZE, Qt::AlignCenter);
94 
95  m_subGridLayout = new QGridLayout();
96  m_subGridLayout->setHorizontalSpacing(50);
97  m_subGridLayout->setVerticalSpacing(30);
98  m_ui->gridLayout_2->addLayout(m_subGridLayout, 2, 0, 1, 1);
99 
100 
101  m_completedGridLayout = new QGridLayout();
102  m_completedGridLayout->setHorizontalSpacing(50);
103  m_completedGridLayout->setVerticalSpacing(30);
104  m_ui->gridLayout_2->addLayout(m_completedGridLayout, 6, 0, 1, 1);
105 
106  populateMap();
107  populateGrid();
108 
109  // Signals from the main buttons.
110  ParleyDocument* doc = m_mainWindow->parleyDocument();
111  connect(m_ui->newButton, SIGNAL(clicked()), m_mainWindow, SLOT(slotFileNew()));
112  connect(m_ui->openButton, SIGNAL(clicked()), doc, SLOT(slotFileOpen()));
113  connect(m_ui->ghnsButton, SIGNAL(clicked()), doc, SLOT(slotGHNS()));
114 
115  // Signals FROM the signal mappers. The ones TO the signal mappers are
116  // handled below.
117  connect(m_practiceSignalMapper, SIGNAL(mapped(const QString &)),
118  this, SLOT(slotPracticeButtonClicked(const QString &)));
119  connect(m_removeSignalMapper, SIGNAL(mapped(const QString &)),
120  this, SLOT(slotRemoveButtonClicked(const QString &)));
121 
122  KConfigGroup cfg(KSharedConfig::openConfig("parleyrc"), objectName());
123  applyMainWindowSettings(cfg);
124 
125  m_themedBackgroundRenderer = new Practice::ThemedBackgroundRenderer(this, "startpagethemecache.bin");
126 
127  // Set theme and prepare for future theme changes.
128  connect(Prefs::self(), SIGNAL(configChanged()), this, SLOT(setTheme()));
129  setTheme();
130 
131  connect(m_themedBackgroundRenderer, SIGNAL(backgroundChanged(QPixmap)),
132  this, SLOT(backgroundChanged(QPixmap)));
133  connect(m_widget, SIGNAL(sizeChanged()), this, SLOT(updateBackground()));
134 
135  KAction *updateAction = new KAction(this);
136  updateAction->setShortcut(QKeySequence(Qt::Key_F5));
137  updateAction->connect(updateAction, SIGNAL(triggered(bool)), this, SLOT(updateWidgets()));
138  actionCollection()->addAction("update_dashboard", updateAction);
139 }
140 
141 Dashboard::~Dashboard()
142 {
143  KConfigGroup cfg(KSharedConfig::openConfig("parleyrc"), objectName());
144  saveMainWindowSettings(cfg);
145 }
146 
147 
148 void Dashboard::clearGrid()
149 {
150  remove(m_subGridLayout,
151  m_subGridLayout->rowCount() - 1, m_subGridLayout->columnCount() - 1,
152  true);
153  remove(m_completedGridLayout,
154  m_completedGridLayout->rowCount() - 1, m_completedGridLayout->columnCount() - 1,
155  true);
156 }
157 
164 void Dashboard::remove(QGridLayout *layout, int row, int column, bool deleteWidgets)
165 {
166  // We avoid usage of QGridLayout::itemAtPosition() here to improve performance.
167  for (int i = layout->count() - 1; i >= 0; i--) {
168  int r, c, rs, cs;
169  layout->getItemPosition(i, &r, &c, &rs, &cs);
170  if ((r + rs - 1 <= row) || (c + cs - 1 <= column)) {
171  // This layout item is subject to deletion.
172  QLayoutItem *item = layout->takeAt(i);
173  if (deleteWidgets) {
174  deleteChildWidgets(item);
175  }
176  delete item;
177  }
178  }
179 }
180 
184 void Dashboard::deleteChildWidgets(QLayoutItem *item)
185 {
186  if (item->layout()) {
187  // Process all child items recursively.
188  for (int i = 0; i < item->layout()->count(); i++) {
189  deleteChildWidgets(item->layout()->itemAt(i));
190  }
191  }
192  delete item->widget();
193 }
194 
195 void Dashboard::populateMap()
196 {
197  KConfig parleyConfig("parleyrc");
198  KConfigGroup recentFilesGroup(&parleyConfig, "Recent Files");
199  for (int i = recentFilesGroup.keyList().count() / 2; i > 0 ; i--) {
200  QString urlString = recentFilesGroup.readPathEntry("File" + QString::number(i), QString());
201  QString nameString = recentFilesGroup.readEntry("Name" + QString::number(i), QString());
202  m_recentFilesMap.insert(urlString, nameString);
203  }
204 }
205 
206 void Dashboard::populateGrid()
207 {
208  int j = 0, k = 0, jc = 0, kc = 0;
209 
210  QMapIterator<QString, QString> it(m_recentFilesMap);
211  while (it.hasNext()) {
212  it.next();
213  QString urlString = it.key();
214  QString titleString = it.value();
215 
216  KUrl url(urlString);
217  Collection *collection = new Collection(&url, this);
218  collection->close(); // We just want to look at it, not own it, so release the lock.
219 
220  // Automatically initialized.
221  // FIXME: Will be initialized by the KEduVocDocument later.
222  WordCount dueWords;
223  int percentageCompleted = dueWords.percentageCompleted();
224 
225  m_urlArray[k] = url;
226  if (percentageCompleted != 100) {
227  if (j % ROWSIZE == 0) {
228  m_subGridLayout->addItem(new QSpacerItem(50, 1), j / ROWSIZE, 0);
229  j++;
230  }
231  }
232  else {
233  if (jc % ROWSIZE == 0) {
234  m_completedGridLayout->addItem(new QSpacerItem(50,1), jc / ROWSIZE, 0);
235  jc++;
236  }
237  }
238 
239  CollectionWidget* backWidget = new CollectionWidget(collection, &dueWords, this);
240  m_collectionWidgets.append(backWidget);
241  if (percentageCompleted != 100) {
242  backWidget->setFixedSize(COLLWIDTH, COLLHEIGHT1);
243  backWidget->setMinimumSize(COLLWIDTH, COLLHEIGHT1);
244  m_subGridLayout->addWidget(backWidget, j / ROWSIZE, j % ROWSIZE);
245  }
246  else {
247  backWidget->setFixedSize(COLLWIDTH, COLLHEIGHT2);
248  backWidget->setMinimumSize(COLLWIDTH, COLLHEIGHT2);
249  m_completedGridLayout->addWidget(backWidget, jc / ROWSIZE, jc % ROWSIZE);
250  }
251 
252  m_practiceSignalMapper->setMapping(backWidget, urlString);
253  connect(backWidget, SIGNAL(practiceButtonClicked()), m_practiceSignalMapper, SLOT(map()));
254  m_removeSignalMapper->setMapping(backWidget, urlString);
255  connect(backWidget, SIGNAL(removeButtonClicked()), m_removeSignalMapper, SLOT(map()));
256 
257  if (percentageCompleted != 100) {
258  j++;
259  }
260  else {
261  jc++;
262  kc++;
263  }
264 
265  k++;
266  }
267 
268  m_count = k;
269  m_completedGridLayout->addItem(new QSpacerItem(50, 1,
270  QSizePolicy::Expanding, QSizePolicy::Fixed),
271  m_completedGridLayout->rowCount() - 1,
272  m_completedGridLayout->columnCount());
273  m_subGridLayout->addItem(new QSpacerItem(50,1,QSizePolicy::Expanding, QSizePolicy::Fixed),
274  m_subGridLayout->rowCount() - 1, m_subGridLayout->columnCount());
275  if (k - kc) {
276  m_ui->recentLabel->setText(i18n("Active Collections"));
277  } else {
278  m_ui->recentLabel->clear();
279  }
280  if (kc) {
281  m_ui->completedLabel->setText(i18n("Completed Collections"));
282  } else {
283  m_ui->completedLabel->clear();
284  }
285 }
286 
287 void Dashboard::statisticsHandler(KUrl url)
288 {
289 #if 1
290  Q_UNUSED(url);
291 #else
292  if (!m_mainWindow->parleyDocument()->open(url)) {
293  return;
294  }
295 
296  // Find due words. TODO find a better way.
297  m_mainWindow->m_sessionManager.setDocument(m_mainWindow->parleyDocument()->document());
298 
299  qDebug()<<"Session Manager, allEntryCount="<<m_mainWindow->m_sessionManager.allDueEntryCount();
300  statisticsWidget->setDocument(m_mainWindow->parleyDocument()->document());
301 
302  // Find the percentage completion, to categorize as active or completed collection.
303  QModelIndex index = statisticsWidget->statisticsModel()->index(0, 2, QModelIndex());
304  qDebug() << "Percentage:" << index.data(StatisticsModel::TotalPercent).toInt();
305 #endif
306 }
307 
308 void Dashboard::slotOpenUrl(const KUrl& url)
309 {
310  if (!m_mainWindow->parleyDocument()->open(url)) {
311  return;
312  }
313  m_mainWindow->showEditor();
314 }
315 
316 void Dashboard::slotPracticeButtonClicked(const QString& urlString)
317 {
318  //kDebug() << urlString;
319 
320  KUrl url(urlString);
321  m_openUrl = url;
322  QTimer::singleShot(0, this, SLOT(slotDoubleClickOpen()));
323 }
324 
325 void Dashboard::slotRemoveButtonClicked(const QString& urlString)
326 {
327  kDebug() << urlString;
328 
329  QMessageBox::StandardButton reply;
330  reply = QMessageBox::question(this, i18n("Remove"),
331  i18n("Are you sure you want to remove this collection?"),
332  QMessageBox::Yes | QMessageBox::No);
333  if (reply == QMessageBox::Yes) {
334  m_recentFilesMap.remove(urlString);
335  m_mainWindow->removeRecentFile(KUrl(urlString));
336  clearGrid();
337  populateGrid();
338  }
339 }
340 
341 void Dashboard::slotDoubleClickOpen()
342 {
343  slotPracticeUrl(m_openUrl);
344 }
345 
346 void Dashboard::slotPracticeUrl(const KUrl & url)
347 {
348  if (!m_mainWindow->parleyDocument()->open(url)) {
349  return;
350  }
351 
352  // This used to go to the practice configuration but both I and
353  //some users wanted to go directly to the practice so I'm testing
354  //out this for a while.
355  m_mainWindow->showPracticeConfiguration();
356  //m_mainWindow->showPractice();
357 }
358 
359 void Dashboard::backgroundChanged(const QPixmap &pixmap)
360 {
361  m_widget->setPixmap(pixmap);
362 }
363 
364 void Dashboard::setTheme()
365 {
366  m_themedBackgroundRenderer->setTheme(Prefs::theme());
367  updateFontColors();
368  updateBackground();
369  m_widget->setContentsMargins(m_themedBackgroundRenderer->contentMargins());
370 }
371 
372 void Dashboard::updateWidgets()
373 {
374  foreach (CollectionWidget *cw, m_collectionWidgets) {
375  cw->updateDue();
376  }
377 }
378 void Dashboard::updateFontColors()
379 {
380  QPalette p(QApplication::palette());
381  QColor c = m_themedBackgroundRenderer->fontColor("Start", p.color(QPalette::Active, QPalette::WindowText));
382  p.setColor(QPalette::Base, Qt::transparent);
383  p.setColor(QPalette::Text, c);
384  p.setColor(QPalette::WindowText, c);
385  m_widget->setPalette(p);
386 }
387 
388 void Dashboard::updateBackground()
389 {
390  m_themedBackgroundRenderer->clearRects();
391  m_themedBackgroundRenderer->addRect("startbackground", QRect(QPoint(), m_widget->size()));
392  QPixmap pixmap = m_themedBackgroundRenderer->getScaledBackground();
393  if (!pixmap.isNull()) {
394  m_widget->setPixmap(pixmap);
395  }
396  m_themedBackgroundRenderer->updateBackground();
397 }
398 
399 #include "dashboard.moc"
QSpacerItem
Dashboard::~Dashboard
~Dashboard()
Definition: dashboard.cpp:141
QModelIndex
statisticsmainwindow.h
QLayout::itemAt
virtual QLayoutItem * itemAt(int index) const =0
QWidget::setPalette
void setPalette(const QPalette &)
QGridLayout::getItemPosition
void getItemPosition(int index, int *row, int *column, int *rowSpan, int *columnSpan)
ParleyMainWindow::removeRecentFile
void removeRecentFile(const KUrl &url)
remove an entry from the list of recent files
Definition: parleymainwindow.cpp:124
ParleyMainWindow::showEditor
void showEditor()
Definition: parleymainwindow.cpp:267
QGridLayout::addWidget
void addWidget(QWidget *widget, int row, int column, QFlags< Qt::AlignmentFlag > alignment)
buttondelegate.h
Dashboard::slotRemoveButtonClicked
void slotRemoveButtonClicked(const QString &urlString)
Definition: dashboard.cpp:325
Dashboard::slotDoubleClickOpen
void slotDoubleClickOpen()
Definition: dashboard.cpp:341
ParleyMainWindow
Definition: parleymainwindow.h:41
QFont
QLayoutItem::widget
virtual QWidget * widget()
COLLHEIGHT1
int COLLHEIGHT1
Definition: collectionwidget.cpp:35
QLayoutItem::layout
virtual QLayout * layout()
Dashboard::slotPracticeButtonClicked
void slotPracticeButtonClicked(const QString &urlString)
Definition: dashboard.cpp:316
ParleyDocument::document
KEduVocDocument * document()
Definition: parleydocument.cpp:97
Practice::ThemedBackgroundRenderer::getScaledBackground
QPixmap getScaledBackground()
Definition: themedbackgroundrenderer.cpp:78
QGridLayout
GradeReferenceWidget
Definition: gradereferencewidget.h:19
QPoint
CollectionWidget::updateDue
void updateDue()
Definition: collectionwidget.cpp:115
ROWSIZE
int ROWSIZE
Definition: dashboard.cpp:56
Practice::ThemedBackgroundRenderer::contentMargins
QMargins contentMargins()
Definition: themedbackgroundrenderer.cpp:190
Prefs::theme
static QString theme()
Get Theme to use for practice and welcome screen.
Definition: prefs.h:51
Collection
Definition: collection.h:34
QTime
COLLWIDTH
int COLLWIDTH
Definition: collectionwidget.cpp:33
collectionwidget.h
COLLHEIGHT2
int COLLHEIGHT2
Definition: collectionwidget.cpp:36
Dashboard::clearGrid
void clearGrid()
Definition: dashboard.cpp:148
QLayoutItem
WordCount
Definition: utils.h:30
Practice::ImageWidget::setScalingEnabled
void setScalingEnabled(bool scaling, bool onlyDownscaling=true)
Definition: imagewidget.cpp:224
QWidget::width
width
Prefs::self
static Prefs * self()
Definition: prefs.cpp:17
QWidget::size
size
QWidget::setMinimumSize
void setMinimumSize(const QSize &)
Practice::ThemedBackgroundRenderer::fontColor
QColor fontColor(const QString &context, const QColor &fallback)
Definition: themedbackgroundrenderer.cpp:106
Dashboard::remove
void remove(QGridLayout *layout, int row, int column, bool deleteWidgets)
Helper function.
Definition: dashboard.cpp:164
parleydocument.h
QRect
QSignalMapper::setMapping
void setMapping(QObject *sender, int id)
ParleyDocument
Definition: parleydocument.h:29
QString::number
QString number(int n, int base)
QGridLayout::count
virtual int count() const
QList::append
void append(const T &value)
QMapIterator
KXmlGuiWindow
Collection::close
void close()
close the document
Definition: collection.cpp:160
Practice::ImageWidget::setKeepAspectRatio
void setKeepAspectRatio(Qt::AspectRatioMode mode)
Definition: imagewidget.cpp:230
QVariant::toInt
int toInt(bool *ok) const
ParleyMainWindow::showPracticeConfiguration
void showPracticeConfiguration()
Definition: parleymainwindow.cpp:272
QMessageBox::question
StandardButton question(QWidget *parent, const QString &title, const QString &text, QFlags< QMessageBox::StandardButton > buttons, StandardButton defaultButton)
QMapIterator::next
Item next()
QGridLayout::takeAt
virtual QLayoutItem * takeAt(int index)
StatisticsModel::TotalPercent
Definition: statisticsmodel.h:28
Practice::ThemedBackgroundRenderer::addRect
void addRect(const QString &name, const QRect &rect)
Definition: themedbackgroundrenderer.cpp:69
Practice::ImageWidget::setPixmap
void setPixmap(const QPixmap &pixmap)
Definition: imagewidget.cpp:200
QGridLayout::setHorizontalSpacing
void setHorizontalSpacing(int spacing)
Dashboard::Dashboard
Dashboard(ParleyMainWindow *parent)
Definition: dashboard.cpp:59
QString
QColor
QMapIterator::key
const Key & key() const
randInt
static int randInt(int low, int high)
Definition: dashboard.cpp:45
QApplication::palette
QPalette palette()
QMapIterator::value
const T & value() const
WordCount::percentageCompleted
int percentageCompleted() const
Definition: utils.cpp:51
QPixmap
Dashboard::statisticsHandler
void statisticsHandler(KUrl url)
Definition: dashboard.cpp:287
QTime::msec
int msec() const
QPixmap::isNull
bool isNull() const
QWidget::setFixedSize
void setFixedSize(const QSize &s)
Practice::SessionManagerBase::setDocument
virtual void setDocument(KEduVocDocument *doc)
Prepare for practice using the entries in this document.
Definition: sessionmanagerbase.cpp:55
Practice::ThemedBackgroundRenderer::setTheme
void setTheme(const QString &theme)
Definition: themedbackgroundrenderer.cpp:50
QGridLayout::setVerticalSpacing
void setVerticalSpacing(int spacing)
Practice::ThemedBackgroundRenderer
Definition: themedbackgroundrenderer.h:31
QTime::currentTime
QTime currentTime()
gradereferencewidget.h
parleymainwindow.h
QGridLayout::rowCount
int rowCount() const
Dashboard::slotPracticeUrl
void slotPracticeUrl(const KUrl &url)
Definition: dashboard.cpp:346
Practice::ThemedBackgroundRenderer::updateBackground
void updateBackground()
Definition: themedbackgroundrenderer.cpp:119
QModelIndex::data
QVariant data(int role) const
QKeySequence
QGridLayout::addItem
void addItem(QLayoutItem *item, int row, int column, int rowSpan, int columnSpan, QFlags< Qt::AlignmentFlag > alignment)
Dashboard::populateGrid
void populateGrid()
Definition: dashboard.cpp:206
QLayout::count
virtual int count() const =0
imagewidget.h
statisticsmodel.h
Dashboard::deleteChildWidgets
void deleteChildWidgets(QLayoutItem *item)
Helper function.
Definition: dashboard.cpp:184
Practice::ImageWidget::setFadingEnabled
void setFadingEnabled(bool fading)
Definition: imagewidget.cpp:235
Practice::ImageWidget
Definition: imagewidget.h:24
CollectionWidget
Definition: collectionwidget.h:35
collection.h
QMap::insert
iterator insert(const Key &key, const T &value)
Practice::ThemedBackgroundRenderer::clearRects
void clearRects()
Definition: themedbackgroundrenderer.cpp:63
ParleyDocument::open
bool open(const KUrl &)
Opens the given url, displays an error message and returns false on failure.
Definition: parleydocument.cpp:191
ParleyMainWindow::parleyDocument
ParleyDocument * parleyDocument()
Return the ParleyDocument member object.
Definition: parleymainwindow.cpp:413
Dashboard::populateMap
void populateMap()
Definition: dashboard.cpp:195
dashboard.h
themedbackgroundrenderer.h
QSignalMapper
QGridLayout::columnCount
int columnCount() const
QPalette
Dashboard::slotOpenUrl
void slotOpenUrl(const KUrl &url)
Definition: dashboard.cpp:308
QMapIterator::hasNext
bool hasNext() const
QWidget::setContentsMargins
void setContentsMargins(int left, int top, int right, int bottom)
QMap::remove
int remove(const Key &key)
QTimer::singleShot
singleShot
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:15:56 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
  • 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