diff --git a/autotests/parleyunittestutilities.cpp b/autotests/parleyunittestutilities.cpp index 1066e73a..502fe926 100644 --- a/autotests/parleyunittestutilities.cpp +++ b/autotests/parleyunittestutilities.cpp @@ -1,62 +1,62 @@ /* Copyright 2014 Andreas Xavier 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 */ /** @file This file collects some utility classes that are used in multiple unit tests **/ #include "parleyunittestutilities.h" using namespace UnitTestUtilities; TemporaryVocDoc::TemporaryVocDoc() :QTemporaryFile( QStringLiteral("XXXXXX.kvtml") ) { this->open(); this->close(); } TemporaryVocDoc::~TemporaryVocDoc() { } MinimalTempVocDoc::MinimalTempVocDoc() { - const QString generator = QString::fromLatin1( "File Locking Unit Tests" ); - const QString author = QString::fromLatin1( "File Locking Test" ); - const QString lang = QString::fromLatin1( "File Locking Language Name" ); - const QString locale = QString::fromLatin1( "en" ) ; + const QString generator = QStringLiteral( "File Locking Unit Tests" ); + const QString author = QStringLiteral( "File Locking Test" ); + const QString lang = QStringLiteral( "File Locking Language Name" ); + const QString locale = QStringLiteral( "en" ) ; KEduVocIdentifier lang0; lang0.setName( lang ); lang0.setLocale( locale); KEduVocDocument *doc = new KEduVocDocument(); doc->setAuthor( author ); doc->appendIdentifier( lang0 ); doc->setGenerator(generator); doc->saveAs(QUrl::fromLocalFile(fileName()), KEduVocDocument::Kvtml); delete doc; } /** Destructor*/ MinimalTempVocDoc::~MinimalTempVocDoc() { } diff --git a/src/collection/vocabularymimedata.cpp b/src/collection/vocabularymimedata.cpp index 8407db12..2458a8fc 100644 --- a/src/collection/vocabularymimedata.cpp +++ b/src/collection/vocabularymimedata.cpp @@ -1,93 +1,93 @@ /*************************************************************************** Copyright 2007 Frederik Gladhorn ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #include "vocabularymimedata.h" #include #include -void VocabularyMimeData::setTranslations(QList translations) +void VocabularyMimeData::setTranslations(const QList &translations) { // list of pointers for drag and drop - for example to assign word types m_translations = translations; // sort the translations into entries to make deep copies for real copy and paste // to only include each expression once QList expressions; foreach(KEduVocTranslation * translation, m_translations) { if (!expressions.contains(translation->entry())) { expressions.append(translation->entry()); } } foreach(KEduVocExpression * expression, expressions) { MimeExpression exp; // deep copy exp.expression = KEduVocExpression(*expression); // copy word types // this sucks but there is not really a better was. copying pointers is not a good idea because copy and paste can be done between different documents. foreach(int i, expression->translationIndices()) { // generate text string representation m_text.append(expression->translation(i)->text()); m_text.append(" - "); // fill in word types independent of pointers KEduVocWordType *type = expression->translation(i)->wordType(); if (type) { // check if it has a type != 0 exp.wordTypes[i].grammarType = expression->translation(i)->wordType()->wordType(); // this may seem weird, but the root element is "word types" so no need to copy that one. while (type->parent()) { exp.wordTypes[i].wordType.prepend(type->name()); type = static_cast(type->parent()); } } } m_expressions.append(exp); m_text.append('\n'); } } QList< KEduVocTranslation * > VocabularyMimeData::translationList() const { return m_translations; } QVariant VocabularyMimeData::retrieveData(const QString & mimeType, QVariant::Type type) const { Q_UNUSED(type) // only use the expression list.expressions // the translation list may be invalid (eg when cut it is no longer valid. // translations can only be used internally for drag and drop!!! if (mimeType == QLatin1String("text/plain")) { return m_text; } return QVariant(); } QStringList VocabularyMimeData::formats() const { return QStringList() << QStringLiteral("text/plain"); } QList< VocabularyMimeData::MimeExpression > VocabularyMimeData::expressionList() const { return m_expressions; } diff --git a/src/collection/vocabularymimedata.h b/src/collection/vocabularymimedata.h index cb83022c..1a0ed633 100644 --- a/src/collection/vocabularymimedata.h +++ b/src/collection/vocabularymimedata.h @@ -1,58 +1,58 @@ /*************************************************************************** Copyright 2007 Frederik Gladhorn ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #ifndef VOCABULARYMIMEDATA_H #define VOCABULARYMIMEDATA_H #include #include #include class KEduVocTranslation; class VocabularyMimeData : public QMimeData { Q_OBJECT public: struct MimeExpression { struct WordTypeStrings { QStringList wordType; // better have this hierarchical KEduVocWordFlags grammarType; }; // all data as deep copy KEduVocExpression expression; // the word types cannot be copied, thus per translation (int) save parent types and the type QMap wordTypes; }; - void setTranslations(QList translation); + void setTranslations(const QList &translation); QList translationList() const; QList expressionList() const; QVariant retrieveData(const QString & mimeType, QVariant::Type type) const Q_DECL_OVERRIDE; QStringList formats() const Q_DECL_OVERRIDE; private: QList m_translations; QList m_expressions; QString m_text; }; #endif diff --git a/src/dashboard/dashboard.cpp b/src/dashboard/dashboard.cpp index dacb392d..a0ece2c7 100644 --- a/src/dashboard/dashboard.cpp +++ b/src/dashboard/dashboard.cpp @@ -1,382 +1,382 @@ /*************************************************************************** Copyright 2014 Inge Wallin ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #include "dashboard.h" #include #include #include #include #include #include //#include #include #include "../utils.h" #include "buttondelegate.h" #include "parleymainwindow.h" #include "parleydocument.h" #include "practice/themedbackgroundrenderer.h" #include "practice/imagewidget.h" #include "statistics/statisticsmainwindow.h" #include "statistics/statisticsmodel.h" #include "collection.h" #include "collectionwidget.h" #include "gradereferencewidget.h" // ================================================================ // class Dashboard int ROWSIZE = 4; // Number of collection widgets (+ 1 initial spacerItem) per row Dashboard::Dashboard(ParleyMainWindow *parent) : KXmlGuiWindow(parent) , m_mainWindow(parent) { // KXmlGui setXMLFile(QStringLiteral("dashboardui.rc")); setObjectName(QStringLiteral("Dashboard")); m_widget = new Practice::ImageWidget(this); m_widget->setScalingEnabled(false, false); m_widget->setKeepAspectRatio(Qt::IgnoreAspectRatio); m_widget->setFadingEnabled(false); m_ui = new Ui::Dashboard(); m_ui->setupUi(m_widget); setCentralWidget(m_widget); m_practiceSignalMapper = new QSignalMapper(this); m_removeSignalMapper = new QSignalMapper(this); QTime time = QTime::currentTime(); qsrand((uint)time.msec()); QFont font = m_ui->recentLabel->font(); font.setBold(true); m_ui->recentLabel->setFont(font); font = m_ui->completedLabel->font(); font.setBold(true); m_ui->completedLabel->setFont(font); m_ui->newButton->setIcon(QIcon::fromTheme(QStringLiteral("document-new"))); m_ui->openButton->setIcon(QIcon::fromTheme(QStringLiteral("document-open"))); m_ui->ghnsButton->setIcon(QIcon::fromTheme(QStringLiteral("get-hot-new-stuff"))); GradeReferenceWidget *gradeReferenceWidget = new GradeReferenceWidget(); gradeReferenceWidget->setMinimumSize(m_widget->width(), 50); m_ui->gridLayout->addWidget(gradeReferenceWidget, 1, 0, 1, ROWSIZE, Qt::AlignCenter); m_subGridLayout = new QGridLayout(); m_subGridLayout->setHorizontalSpacing(50); m_subGridLayout->setVerticalSpacing(30); m_ui->gridLayout_2->addLayout(m_subGridLayout, 2, 0, 1, 1); m_completedGridLayout = new QGridLayout(); m_completedGridLayout->setHorizontalSpacing(50); m_completedGridLayout->setVerticalSpacing(30); m_ui->gridLayout_2->addLayout(m_completedGridLayout, 6, 0, 1, 1); populateMap(); populateGrid(); // Signals from the main buttons. ParleyDocument* doc = m_mainWindow->parleyDocument(); connect(m_ui->newButton, &QAbstractButton::clicked, m_mainWindow, &ParleyMainWindow::slotFileNew); connect(m_ui->openButton, &QAbstractButton::clicked, doc, &ParleyDocument::slotFileOpen); connect(m_ui->ghnsButton, &QAbstractButton::clicked, doc, &ParleyDocument::slotGHNS); // Signals FROM the signal mappers. The ones TO the signal mappers are // handled below. connect(m_practiceSignalMapper, SIGNAL(mapped(QString)), this, SLOT(slotPracticeButtonClicked(QString))); connect(m_removeSignalMapper, SIGNAL(mapped(QString)), this, SLOT(slotRemoveButtonClicked(QString))); KConfigGroup cfg(KSharedConfig::openConfig(QStringLiteral("parleyrc")), objectName()); applyMainWindowSettings(cfg); m_themedBackgroundRenderer = new Practice::ThemedBackgroundRenderer(this, QStringLiteral("startpagethemecache.bin")); // Set theme and prepare for future theme changes. connect(Prefs::self(), &KCoreConfigSkeleton::configChanged, this, &Dashboard::setTheme); setTheme(); connect(m_themedBackgroundRenderer, &Practice::ThemedBackgroundRenderer::backgroundChanged, this, &Dashboard::backgroundChanged); connect(m_widget, &Practice::ImageWidget::sizeChanged, this, &Dashboard::updateBackground); QAction *updateAction = new QAction(this); updateAction->connect(updateAction, &QAction::triggered, this, &Dashboard::updateWidgets); actionCollection()->addAction(QStringLiteral("update_dashboard"), updateAction); actionCollection()->setDefaultShortcut(updateAction, QKeySequence(Qt::Key_F5)); } Dashboard::~Dashboard() { KConfigGroup cfg(KSharedConfig::openConfig(QStringLiteral("parleyrc")), objectName()); saveMainWindowSettings(cfg); } void Dashboard::clearGrid() { remove(m_subGridLayout, m_subGridLayout->rowCount() - 1, m_subGridLayout->columnCount() - 1, true); remove(m_completedGridLayout, m_completedGridLayout->rowCount() - 1, m_completedGridLayout->columnCount() - 1, true); } /** * Helper function. Removes all layout items within the given @a layout * which either span the given @a row or @a column. If @a deleteWidgets * is true, all concerned child widgets become not only removed from the * layout, but also deleted. */ void Dashboard::remove(QGridLayout *layout, int row, int column, bool deleteWidgets) { // We avoid usage of QGridLayout::itemAtPosition() here to improve performance. for (int i = layout->count() - 1; i >= 0; i--) { int r, c, rs, cs; layout->getItemPosition(i, &r, &c, &rs, &cs); if ((r + rs - 1 <= row) || (c + cs - 1 <= column)) { // This layout item is subject to deletion. QLayoutItem *item = layout->takeAt(i); if (deleteWidgets) { deleteChildWidgets(item); } delete item; } } } /** * Helper function. Deletes all child widgets of the given layout @a item. */ void Dashboard::deleteChildWidgets(QLayoutItem *item) { if (item->layout()) { // Process all child items recursively. for (int i = 0; i < item->layout()->count(); i++) { deleteChildWidgets(item->layout()->itemAt(i)); } } delete item->widget(); } void Dashboard::populateMap() { KConfig parleyConfig(QStringLiteral("parleyrc")); KConfigGroup recentFilesGroup(&parleyConfig, "Recent Files"); for (int i = recentFilesGroup.keyList().count() / 2; i > 0 ; i--) { QString urlString = recentFilesGroup.readPathEntry("File" + QString::number(i), QString()); QString nameString = recentFilesGroup.readEntry("Name" + QString::number(i), QString()); m_recentFilesMap.insert(urlString, nameString); } } void Dashboard::populateGrid() { int j = 0, k = 0, jc = 0, kc = 0; QMapIterator it(m_recentFilesMap); while (it.hasNext()) { it.next(); QString urlString = it.key(); QString titleString = it.value(); QUrl url(QUrl::fromLocalFile(urlString)); Collection *collection = new Collection(&url, this); WordCount dueWords; int percentageCompleted = dueWords.percentageCompleted(); m_urlArray[k] = url; if (percentageCompleted != 100) { if (j % ROWSIZE == 0) { m_subGridLayout->addItem(new QSpacerItem(50, 1), j / ROWSIZE, 0); j++; } } else { if (jc % ROWSIZE == 0) { m_completedGridLayout->addItem(new QSpacerItem(50,1), jc / ROWSIZE, 0); jc++; } } CollectionWidget* backWidget = new CollectionWidget(collection, &dueWords, this); m_collectionWidgets.append(backWidget); if (percentageCompleted != 100) { backWidget->setFixedSize(COLLWIDTH, COLLHEIGHT1); backWidget->setMinimumSize(COLLWIDTH, COLLHEIGHT1); m_subGridLayout->addWidget(backWidget, j / ROWSIZE, j % ROWSIZE); } else { backWidget->setFixedSize(COLLWIDTH, COLLHEIGHT2); backWidget->setMinimumSize(COLLWIDTH, COLLHEIGHT2); m_completedGridLayout->addWidget(backWidget, jc / ROWSIZE, jc % ROWSIZE); } m_practiceSignalMapper->setMapping(backWidget, urlString); connect(backWidget, SIGNAL(practiceButtonClicked()), m_practiceSignalMapper, SLOT(map())); m_removeSignalMapper->setMapping(backWidget, urlString); connect(backWidget, SIGNAL(removeButtonClicked()), m_removeSignalMapper, SLOT(map())); if (percentageCompleted != 100) { j++; } else { jc++; kc++; } k++; } m_count = k; m_completedGridLayout->addItem(new QSpacerItem(50, 1, QSizePolicy::Expanding, QSizePolicy::Fixed), m_completedGridLayout->rowCount() - 1, m_completedGridLayout->columnCount()); m_subGridLayout->addItem(new QSpacerItem(50,1,QSizePolicy::Expanding, QSizePolicy::Fixed), m_subGridLayout->rowCount() - 1, m_subGridLayout->columnCount()); if (k - kc) { m_ui->recentLabel->setText(i18n("Active Collections")); } else { m_ui->recentLabel->clear(); } if (kc) { m_ui->completedLabel->setText(i18n("Completed Collections")); } else { m_ui->completedLabel->clear(); } } -void Dashboard::statisticsHandler(QUrl url) +void Dashboard::statisticsHandler(const QUrl &url) { #if 1 Q_UNUSED(url); #else if (!m_mainWindow->parleyDocument()->open(url)) { return; } // Find due words. TODO find a better way. m_mainWindow->m_sessionManager.setDocument(m_mainWindow->parleyDocument()->document()); qDebug()<<"Session Manager, allEntryCount="<m_sessionManager.allDueEntryCount(); statisticsWidget->setDocument(m_mainWindow->parleyDocument()->document()); // Find the percentage completion, to categorize as active or completed collection. QModelIndex index = statisticsWidget->statisticsModel()->index(0, 2, QModelIndex()); qDebug() << "Percentage:" << index.data(StatisticsModel::TotalPercent).toInt(); #endif } void Dashboard::slotOpenUrl(const QUrl& url) { if (!m_mainWindow->parleyDocument()->open(url)) { return; } m_mainWindow->showEditor(); } void Dashboard::slotPracticeButtonClicked(const QString& urlString) { //qDebug() << urlString; QUrl url( QUrl::fromLocalFile(urlString) ); m_openUrl = url; QTimer::singleShot(0, this, &Dashboard::slotDoubleClickOpen); } void Dashboard::slotRemoveButtonClicked(const QString& urlString) { qDebug() << urlString; QMessageBox::StandardButton reply; reply = QMessageBox::question(this, i18n("Remove"), i18n("Are you sure you want to remove this collection?"), QMessageBox::Yes | QMessageBox::No); if (reply == QMessageBox::Yes) { m_recentFilesMap.remove(urlString); m_mainWindow->removeRecentFile(QUrl::fromLocalFile(urlString )); clearGrid(); populateGrid(); } } void Dashboard::slotDoubleClickOpen() { slotPracticeUrl(m_openUrl); } void Dashboard::slotPracticeUrl(const QUrl & url) { if (!m_mainWindow->parleyDocument()->open(url)) { return; } // This used to go to the practice configuration but both I and //some users wanted to go directly to the practice so I'm testing //out this for a while. m_mainWindow->showPracticeConfiguration(); //m_mainWindow->showPractice(); } void Dashboard::backgroundChanged(const QPixmap &pixmap) { m_widget->setPixmap(pixmap); } void Dashboard::setTheme() { m_themedBackgroundRenderer->setTheme(Prefs::theme()); updateFontColors(); updateBackground(); m_widget->setContentsMargins(m_themedBackgroundRenderer->contentMargins()); } void Dashboard::updateWidgets() { foreach (CollectionWidget *cw, m_collectionWidgets) { cw->updateDue(); } } void Dashboard::updateFontColors() { QPalette p(QApplication::palette()); QColor c = m_themedBackgroundRenderer->fontColor(QStringLiteral("Start"), p.color(QPalette::Active, QPalette::WindowText)); p.setColor(QPalette::Base, Qt::transparent); p.setColor(QPalette::Text, c); p.setColor(QPalette::WindowText, c); m_widget->setPalette(p); } void Dashboard::updateBackground() { m_themedBackgroundRenderer->clearRects(); m_themedBackgroundRenderer->addRect(QStringLiteral("startbackground"), QRect(QPoint(), m_widget->size())); QPixmap pixmap = m_themedBackgroundRenderer->getScaledBackground(); if (!pixmap.isNull()) { m_widget->setPixmap(pixmap); } m_themedBackgroundRenderer->updateBackground(); } diff --git a/src/dashboard/dashboard.h b/src/dashboard/dashboard.h index adaa1c06..464e6a42 100644 --- a/src/dashboard/dashboard.h +++ b/src/dashboard/dashboard.h @@ -1,90 +1,90 @@ /*************************************************************************** Copyright 2008-2010 Daniel Laidig ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #ifndef DASHBOARD_H #define DASHBOARD_H #include "ui_dashboard.h" #include "statistics/statisticsmainwindow.h" #include #include #include static const int N = 50; class ParleyMainWindow; class QStandardItemModel; namespace Practice { class ThemedBackgroundRenderer; class ImageWidget; } class CollectionWidget; class RemoveButton; class Dashboard : public KXmlGuiWindow { Q_OBJECT public: explicit Dashboard(ParleyMainWindow *parent); ~Dashboard(); public slots: void slotOpenUrl(const QUrl& url); void slotPracticeUrl(const QUrl& url); //void slotDoubleClicked(const QModelIndex& index); void slotDoubleClickOpen(); //void updateRecentFilesModel(); void populateGrid(); void populateMap(); void clearGrid(); void slotPracticeButtonClicked(const QString& urlString); void slotRemoveButtonClicked(const QString& urlString); - void statisticsHandler(QUrl url); + void statisticsHandler(const QUrl &url); void remove(QGridLayout *layout, int row, int column, bool deleteWidgets); void deleteChildWidgets(QLayoutItem *item); private slots: void setTheme(); void updateWidgets(); void backgroundChanged(const QPixmap& pixmap); void updateFontColors(); void updateBackground(); private: Ui::Dashboard *m_ui; ParleyMainWindow *m_mainWindow; StatisticsMainWindow *m_statisticsWidget; Practice::ThemedBackgroundRenderer *m_themedBackgroundRenderer; Practice::ImageWidget* m_widget; QMap m_recentFilesMap; // url, name QUrl m_openUrl; QGridLayout *m_subGridLayout; QGridLayout *m_completedGridLayout; QList m_collectionWidgets; // List of the widgets in the dashboard. // The parts of the collections QUrl m_urlArray[N]; QSignalMapper *m_practiceSignalMapper; // For the practice buttons QSignalMapper *m_removeSignalMapper; // For the remove buttons int m_count; }; #endif diff --git a/src/practice/audiobutton.cpp b/src/practice/audiobutton.cpp index b5f584c7..6623eb08 100644 --- a/src/practice/audiobutton.cpp +++ b/src/practice/audiobutton.cpp @@ -1,74 +1,74 @@ /*************************************************************************** Copyright 2010 Daniel Laidig ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #include "audiobutton.h" #include using namespace Practice; AudioButton::AudioButton(QWidget *parent) : QToolButton(parent), m_player(0) { setEnabled(false); QIcon setIcon(QIcon::fromTheme(QStringLiteral("media-playback-start"))); setText(i18n("Play")); setToolTip(i18n("Play")); connect(this, &AudioButton::clicked, this, &AudioButton::playAudio); connect(parent, SIGNAL(stopAudio()), this, SLOT(stopAudio())); } -void AudioButton::setSoundFile(QUrl soundFile) +void AudioButton::setSoundFile(const QUrl &soundFile) { m_url = soundFile; setEnabled(!m_url.isEmpty() && m_url.isLocalFile()); } void AudioButton::playAudio() { if (!m_player) { m_player = new QMediaPlayer( this ); connect(m_player, &QMediaPlayer::stateChanged, this, &AudioButton::playerStateChanged); } else { if (m_player->state() == QMediaPlayer::PlayingState) { m_player->stop(); } } m_player->setMedia(m_url); m_player->setVolume(50); m_player->play(); } void AudioButton::stopAudio() { if (m_player && m_player->state() == QMediaPlayer::PlayingState) { m_player->stop(); } } void AudioButton::playerStateChanged(QMediaPlayer::State newState) { switch (newState) { case QMediaPlayer::PlayingState: setIcon(QIcon::fromTheme(QStringLiteral("media-playback-stop"))); setText(i18n("Stop")); setToolTip(i18n("Stop")); break; case QMediaPlayer::StoppedState: case QMediaPlayer::PausedState: setIcon(QIcon::fromTheme(QStringLiteral("media-playback-start"))); setToolTip(i18n("Play")); setText(i18n("Play")); break; } } diff --git a/src/practice/audiobutton.h b/src/practice/audiobutton.h index 4465dd87..e6c45c6f 100644 --- a/src/practice/audiobutton.h +++ b/src/practice/audiobutton.h @@ -1,45 +1,45 @@ /*************************************************************************** Copyright 2010 Daniel Laidig ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #ifndef PRACTICE_AUDIOBUTTON_H #define PRACTICE_AUDIOBUTTON_H #include #include #include class QMediaPlayer; namespace Practice { class AudioButton : public QToolButton { Q_OBJECT public: explicit AudioButton(QWidget *parent); - void setSoundFile(QUrl url); + void setSoundFile(const QUrl &url); private Q_SLOTS: void playAudio(); void stopAudio(); void playerStateChanged(QMediaPlayer::State newState); private: QMediaPlayer* m_player; ///< media object for the files QUrl m_url; }; } #endif // PRACTICE_AUDIOBUTTON_H diff --git a/src/practice/statustogglebutton.cpp b/src/practice/statustogglebutton.cpp index be29aabe..55c524ff 100644 --- a/src/practice/statustogglebutton.cpp +++ b/src/practice/statustogglebutton.cpp @@ -1,63 +1,63 @@ /*************************************************************************** Copyright 2010 Daniel Laidig ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #include "statustogglebutton.h" #include using namespace Practice; -void StatusToggleButton::setPixmaps(QPixmap defaultPixmap, QPixmap hoverPixmap, QPixmap pressedPixmap) +void StatusToggleButton::setPixmaps(const QPixmap &defaultPixmap, const QPixmap &hoverPixmap, const QPixmap &pressedPixmap) { if (m_current == 1) { setPixmap(hoverPixmap); } else { setPixmap(defaultPixmap); } m_defaultPixmap = defaultPixmap; m_hoverPixmap = hoverPixmap; m_pressedPixmap = pressedPixmap; } void StatusToggleButton::mousePressEvent(QMouseEvent *e) { if (e->button() == Qt::LeftButton) { this->setFadingEnabled(false); setPixmap(m_pressedPixmap); } } void StatusToggleButton::mouseReleaseEvent(QMouseEvent *e) { if (!m_defaultPixmap.isNull() && e->button() == Qt::LeftButton) { emit clicked(); if (m_current == 1) { setPixmap(m_hoverPixmap); } else { setPixmap(m_defaultPixmap); } } this->setFadingEnabled(true); } void StatusToggleButton::enterEvent(QEvent *) { m_current = 1; setPixmap(m_hoverPixmap); } void StatusToggleButton::leaveEvent(QEvent *) { m_current = 0; setPixmap(m_defaultPixmap); } diff --git a/src/practice/statustogglebutton.h b/src/practice/statustogglebutton.h index c9f7878c..58b26948 100644 --- a/src/practice/statustogglebutton.h +++ b/src/practice/statustogglebutton.h @@ -1,50 +1,50 @@ /*************************************************************************** Copyright 2010 Daniel Laidig ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #ifndef PRACTICE_STATUSTOGGLEBUTTON_H #define PRACTICE_STATUSTOGGLEBUTTON_H #include "imagewidget.h" #include //TODO namespace Practice { class StatusToggleButton : public ImageWidget { Q_OBJECT public: StatusToggleButton(QWidget* parent = 0) : ImageWidget(parent), m_current(0) { setMouseTracking(true); } - void setPixmaps(QPixmap defaultPixmap, QPixmap hoverPixmap, QPixmap pressedPixmap); + void setPixmaps(const QPixmap &defaultPixmap, const QPixmap &hoverPixmap, const QPixmap &pressedPixmap); protected: void mousePressEvent(QMouseEvent *e) Q_DECL_OVERRIDE; void mouseReleaseEvent(QMouseEvent *e) Q_DECL_OVERRIDE; void enterEvent(QEvent *) Q_DECL_OVERRIDE; void leaveEvent(QEvent *) Q_DECL_OVERRIDE; signals: void clicked(); private: QPixmap m_defaultPixmap; QPixmap m_hoverPixmap; QPixmap m_pressedPixmap; int m_current; }; } #endif // PRACTICE_STATUSTOGGLEBUTTON_H diff --git a/src/scripts/script.cpp b/src/scripts/script.cpp index b3a0c0ae..dedcb38b 100644 --- a/src/scripts/script.cpp +++ b/src/scripts/script.cpp @@ -1,124 +1,124 @@ /*************************************************************************** Copyright 2008 Avgoustinos Kadis ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #include "script.h" #include #include #include -Script::Script(QString file) +Script::Script(const QString &file) { m_file = file; m_activated = false; } Script::~Script() { delete m_object; } bool Script::isActivated() { return m_activated; } void Script::activate() { qDebug() << "Activating Script" << fileName(); if (isActivated()) { qDebug() << "Script already activated"; return; } if (!exists()) { qDebug() << "Script file given does not exist"; m_errorMessage = i18n("The script file does not exist."); return; } // Create the script container. m_object is the parent QObject, // so that our action instance will be destroyed once the m_object // is destroyed. m_object = new QObject(); Kross::Action* action = new Kross::Action(m_object, m_file); // Publish our myobject instance and connect signals with // scripting functions. QMapIterator i(m_scriptObjects); while (i.hasNext()) { i.next(); qDebug() << i.key(); action->addObject(i.value() , i.key(), Kross::ChildrenInterface::AutoConnectSignals); } // Set the file to be execute action->setFile(m_file); // Execute the script. action->trigger(); m_activated = !action->isFinalized(); if (!m_activated) { qDebug() << "Script not activated"; QString msg = action->errorMessage(); QString trace = action->errorTrace(); msg.replace('<', QLatin1String("<")).replace('\n', QLatin1String("
")); trace.replace('<', QLatin1String("<")).replace('\n', QLatin1String("
")); m_errorMessage = "

" + i18n("Error in file %1 at line %2:", fileName(), action->errorLineNo()) + "
" + msg + "
" + i18nc("debug information in error message", "Backtrace:") + "
" + trace + "

"; } } void Script::deactivate() { delete m_object; m_activated = false; } bool Script::exists() { QFileInfo fileInfo(m_file); return fileInfo.exists(); } QString Script::fileName() { return m_file; } -void Script::addObject(QString name, QObject * object) +void Script::addObject(const QString &name, QObject * object) { m_scriptObjects.insert(name, object); } -void Script::addObjects(QMap objects) +void Script::addObjects(const QMap &objects) { m_scriptObjects.unite(objects); } QString Script::errorMessage() { return m_errorMessage; } diff --git a/src/scripts/script.h b/src/scripts/script.h index e48a08b7..b5736508 100644 --- a/src/scripts/script.h +++ b/src/scripts/script.h @@ -1,89 +1,89 @@ /*************************************************************************** Copyright 2008 Avgoustinos Kadis ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #ifndef SCRIPT_H #define SCRIPT_H #include "scripting/parley.h" #include #include #include #include /** * This class represents the activated script and is used by the ScriptManager * to activate/deactivate scripts. * * @author Avgoustinos Kadis */ class Script: public QObject { Q_OBJECT public: /** * Script class constructor * * @param file The path to the script file to be activated (executed) */ - explicit Script(QString file); + explicit Script(const QString &file); ~Script(); /** * Returns true if the script was successfully activated; false otherwise */ bool isActivated(); /** * Activates the script */ void activate(); /** * Deactivate the script */ void deactivate(); /** * Checks if the script file assigned to the Script object exists as a file on the * given path. * * @return True if the script file exists * False if it does not exist */ bool exists(); /** * Returns the file that was given as parameter to the constructor */ QString fileName(); /** * Add an object to be accessible by the script * @param name Name to appear in the script * @param object Object to be accessible by the script */ - void addObject(QString name, QObject * object); + void addObject(const QString &name, QObject * object); /** * Adds more than one scripting Objects to the script * @param objects Map of the objects to add */ - void addObjects(QMap objects); + void addObjects(const QMap &objects); /** * Returns an html error message if there have been errors in the script. */ QString errorMessage(); private: bool m_activated; QString m_file; QPointer m_object; QMap m_scriptObjects; QString m_errorMessage; }; #endif diff --git a/src/scripts/scripting/expression.cpp b/src/scripts/scripting/expression.cpp index 24fcd827..3d53dcf1 100644 --- a/src/scripts/scripting/expression.cpp +++ b/src/scripts/scripting/expression.cpp @@ -1,110 +1,110 @@ /*************************************************************************** Copyright 2008 Avgoustinos Kadis ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #include "expression.h" #include "translation.h" namespace Scripting { Expression::Expression() { m_expression = new KEduVocExpression(); } Expression::Expression(const QString & expression) { m_expression = new KEduVocExpression(expression); } Expression::Expression(const QStringList & translations) { m_expression = new KEduVocExpression(translations); } Expression::Expression(KEduVocExpression * expression) : QObject(), m_expression(expression) { } Expression::Expression(const Expression & other) : QObject() { m_expression = other.kEduVocExpression(); } Expression::~Expression() { } QVariantList Expression::translationIndices() const { QVariantList vlist; foreach(int k, m_expression->translationIndices()) { vlist.push_back(QVariant(k)); } return vlist; } QVariantList Expression::translations() const { //build a list of all the translations QList translations; foreach(int k, m_expression->translationIndices()) { if (m_expression->translation(k)) translations.push_back(m_expression->translation(k)); } //convert it to QVariantList and return it return toVariantList (translations); } QStringList Expression::translationTexts() const { //build a list of all the translation texts QStringList list; foreach(int k, m_expression->translationIndices()) { if (m_expression->translation(k)) list << m_expression->translation(k)->text(); } return list; } // Expression & Expression::operator= ( const Expression &other ) // { // m_expression = other.kEduVocEntry(); // return ( *this ); // } // bool Expression::operator== ( const Expression &other ) const // { // return m_expression == other.kEduVocEntry(); // } // void Expression::setTranslation( int index, QObject* translation ) { // Translation * t = dynamic_cast(translation); // m_expression->setTranslation(index,t->kEduVocTranslation()); // } -void Expression::setTranslations(QStringList translations) +void Expression::setTranslations(const QStringList &translations) { delete m_expression; m_expression = new KEduVocExpression(translations); } QObject* Expression::translation(int index) const { return new Translation(m_expression->translation(index)); } } diff --git a/src/scripts/scripting/expression.h b/src/scripts/scripting/expression.h index b2c20ffd..cc0ce401 100644 --- a/src/scripts/scripting/expression.h +++ b/src/scripts/scripting/expression.h @@ -1,209 +1,209 @@ /*************************************************************************** Copyright 2008 Avgoustinos Kadis ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #ifndef SCRIPTINGEXPRESSION_H #define SCRIPTINGEXPRESSION_H #include #include "lesson.h" #include #include namespace Scripting { class Translation; /** * This class represents @author Avgoustinos Kadis */ class Expression : public QObject { Q_OBJECT /// Parent lesson (if any) Q_PROPERTY(QObject * lesson READ lesson) /// Specifies if the entry is active or not (enabled for queries or not) Q_PROPERTY(bool active READ isActive WRITE setActive) // Q_PROPERTY ( int sizeHint READ sizeHint WRITE setSizeHint) public: /* default constructor for an empty vocabulary expression */ Expression(); /* Constructor for a vocabulary expression with one translation * * @param expression translation */ explicit Expression(const QString & expression); /* * Constructor for vocabulary expression with more than one translation * @param translations */ explicit Expression(const QStringList & translations); Expression(const Expression & other); /* * Constructor from a KEduVocExpression (doesn't exist in KEduVocExpression) * @param expression KEduVocExpression object */ explicit Expression(KEduVocExpression * expression); ~Expression(); KEduVocExpression * kEduVocExpression() const { return m_expression; } template QVariantList toVariantList(QList objList) const; //Property: lesson [get method - read-only] QObject * lesson() const { return new Lesson(m_expression->lesson()); } /* returns flag if entry is activated for queries */ bool isActive() const { return m_expression->isActive(); } /* set entry active (enabled for queries) */ void setActive(bool flag = true) { m_expression->setActive(flag); } //Property: sizeHing [get/set methods] (not implemented in KEduVocExpression) //int sizeHint() const { return m_expression->sizeHint(); } //void setSizeHint( int sizeHint ) { m_expression->setSizeHint(sizeHint); } //for assignlable type // Expression & operator= ( const Expression &other ); // bool operator== ( const Expression &other ) const; public slots: /** reset all grades of the entry * @param index identifier (language) */ void resetGrades(int index) { m_expression->resetGrades(index); } //not implemented in KEduVocExpression // void setTranslation( int index, QObject* translation ); /** * Add a translation to this expression * @code * #how to set translations of an entry with setTranslation(index,expression) * import Parley * lesson = Parley.doc.findLesson("Lesson 2") * if lesson != None: * new_entry = lesson.newEntry() * new_entry.setTranslation(0,"day") * new_entry.setTranslation(0,"jour") * lesson.appendEntry(new_entry) * @endcode * @param index number of translation = the identifier * @param expression the translation */ void setTranslation(int index, const QString &expression) { m_expression->setTranslation(index, expression); } /** * Sets the translations of an entry. All previous translations are removed * @code * #how to set the translations of an entry * import Parley * new_entry = Parley.activeLesson.newEntry() * new_entry.setTranslations(["good morning","bonjour"]) * Parley.activeLesson.appendEntry(new_entry) * @endcode * @param translations A list of strings with the translations (must be in correct language order) */ - void setTranslations(QStringList translations); + void setTranslations(const QStringList &translations); /** * removes a translation * @code * #how to remove all the translations of a language from a lesson * import Parley * for entry in Parley.activeLesson.entries(True): * entry.removeTranslation(1) * @endcode * @param index number of translation 1..x */ void removeTranslation(int index) { m_expression->removeTranslation(index); } /** * Get the translation of a specified @p index (translation index) * @param index of the language identifier * @return A Translation object */ QObject* translation(int index) const; /** Returns a list of integers (the translation indices) */ QVariantList translationIndices() const; /** * Returns a list of all the translations of an entry * @code * #iterate through all the translations of all the entries of the root lesson and print their text * for entry in Parley.doc.rootLesson.entries(True): * for tr in entry.translations(): * print tr.text * @endcode * @return A list of Translation objects */ QVariantList translations() const; /** * Returns a list of all the translations texts of an entry * @code * #iterate through all the translations of all the entries of the root lesson and print their text * for entry in Parley.doc.rootLesson.entries(True): * print entry.translationTexts() * @endcode * @return A list of strings (list of translation.text property of every translation) */ QStringList translationTexts() const; private: KEduVocExpression* m_expression; }; //Template functions should not be separated from their definition (must be in the header file) template QVariantList Expression::toVariantList(QList objList) const { QVariantList list; foreach(T * t, objList) { QObject * obj = new S(t); list.push_back(qVariantFromValue(obj)); } return list; } } #endif diff --git a/src/scripts/scripting/identifier.h b/src/scripts/scripting/identifier.h index cd814493..1be36ad0 100644 --- a/src/scripts/scripting/identifier.h +++ b/src/scripts/scripting/identifier.h @@ -1,196 +1,196 @@ /*************************************************************************** Copyright 2008 Avgoustinos Kadis ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #ifndef SCRIPTINGIDENTIFIER_H #define SCRIPTINGIDENTIFIER_H #include #include #include namespace Scripting { /** * Identifier class can be accessed from Document class and is used for specifying the document languages, articles and personal pronouns. * @code #how to specify the articles and personal pronouns of a language (German in this example) import Parley newid = Parley.doc.newIdentifier() newid.name = "German" newid.locale = "de" newid.setArticle("der",Parley.Singular|Parley.Definite|Parley.Masculine) newid.setArticle("die",Parley.Singular|Parley.Definite|Parley.Feminine) newid.setArticle("das",Parley.Singular|Parley.Definite|Parley.Neuter) newid.setArticle("ein",Parley.Singular|Parley.Indefinite|Parley.Masculine) newid.setArticle("eine",Parley.Singular|Parley.Indefinite|Parley.Feminine) newid.setArticle("ein",Parley.Singular|Parley.Indefinite|Parley.Neuter) newid.setPersonalPronoun("ich",Parley.Singular|Parley.First) newid.setPersonalPronoun("du",Parley.Singular|Parley.Second) newid.setPersonalPronoun("er",Parley.Singular|Parley.Third|Parley.Masculine) newid.setPersonalPronoun("sie",Parley.Singular|Parley.Third|Parley.Feminine) newid.setPersonalPronoun("es",Parley.Singular|Parley.Third|Parley.Neuter) newid.setPersonalPronoun("wir",Parley.Plural|Parley.First) newid.setPersonalPronoun("ihr",Parley.Plural|Parley.Second) newid.setPersonalPronoun("sie",Parley.Plural|Parley.Third) index = Parley.doc.appendIdentifier(newid) @endcode * * @author Avgoustinos Kadis */ class Identifier : public QObject { Q_OBJECT Q_PROPERTY(QString name READ name WRITE setName) Q_PROPERTY(QString locale READ locale WRITE setLocale) public: Identifier(); explicit Identifier(KEduVocIdentifier * identifier); explicit Identifier(KEduVocIdentifier & identifier); ~Identifier(); KEduVocIdentifier * kEduVocIdentifier() { return m_identifier; } /** * Name of this identifier. (English, Anatomy, Fruit salad...) * @return name */ QString name() const { return m_identifier->name(); } /** * Set the name * @param name */ void setName(const QString& name) { m_identifier->setName(name); } /** * The locale of the contents: en, de, es, ... * @return locale */ QString locale() const { return m_identifier->locale(); } /** * Set the locale * @param name */ void setLocale(const QString& name) { m_identifier->setLocale(name); } public Q_SLOTS: /**** Article Functions ****/ /** * Articles (a, the in English, el, la,... in Spanish) * @returns articles */ // KEduVocArticle article() const; /** * Returns the article in the given number, definiteness and gender flags: * * - Number flags: Parley.Singular, Parley.Dual, Parley.Plural * - Definiteness flags: Parley.Definite, Parley.Indefinite * - Gender flags: Parley.Masculine, Parley.Feninine, Parley.Neuter * * @param flags Flags to indicate which article to return * @return A string containing the requested article. Empty string if does not exist */ QString article(const KEduVocWordFlags& flags); /** * Sets the @p article in the given number, definiteness and gender flags: * * - Number flags: Parley.Singular, Parley.Dual, Parley.Plural * - Definiteness flags: Parley.Definite, Parley.Indefinite * - Gender flags: Parley.Masculine, Parley.Feninine, Parley.Neuter * * @param article The article to set * @param flags Flags to indicate which article to set */ void setArticle(const QString& article, const KEduVocWordFlags& flags); /**** Personal Pronoun Functions ****/ /** * Get the personal pronouns for this identifier * @returns a KEduVocPersonalPronoun containing the personal pronouns */ // KEduVocPersonalPronoun personalPronouns() const; // QString personalPronoun ( const QString & number, const QString & person ); QString personalPronoun(const KEduVocWordFlags& flags) const; /** * Sets personal pronouns * @param conjugation a conjugation of the personal pronoun * @param flags the KEduVocWordFlags flags */ // void setPersonalPronouns ( const KEduVocPersonalPronoun &pronouns ); // void setPersonalPronoun ( const QString& personalPronoun, const QString & number, const QString & person ); void setPersonalPronoun(const QString& conjugation, const KEduVocWordFlags& flags); QStringList personalPronouns(); /** * Sets the document tenses * @code * #how to add new tenses to a language * import Parley * for ident in Parley.doc.identifiers(): * T = ident.tenses() * print T * T.append("Present Perfect") * T.append("Past Simple") * T.append("Past Perfect") * ident.setTenses(T) * print ident.tenses() * @endcode * @param names A string list of the document tenses we want to be using */ - void setTenses(QStringList names) { + void setTenses(const QStringList &names) { m_identifier->setTenseList(names); } /** * Gets the language tenses (see example in Identifier::setTenses()) * @return A string list of all the language tenses */ QStringList tenses() const { return m_identifier->tenseList(); } private: KEduVocIdentifier * m_identifier; }; } #endif diff --git a/src/scripts/scripting/lesson.cpp b/src/scripts/scripting/lesson.cpp index 5766cce7..19d7df29 100644 --- a/src/scripts/scripting/lesson.cpp +++ b/src/scripts/scripting/lesson.cpp @@ -1,151 +1,151 @@ /*************************************************************************** Copyright 2008 Avgoustinos Kadis ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #include "lesson.h" #include "expression.h" #include #include namespace Scripting { Lesson::Lesson(KEduVocLesson * lesson) : Container(lesson), m_lesson(lesson) { } Lesson::Lesson(KEduVocContainer * container) { m_lesson = static_cast(container); m_container = m_lesson; } Lesson::Lesson(const QString& name) { m_lesson = new KEduVocLesson(name); m_container = m_lesson; } Lesson::~Lesson() { } QList flattenLessons(KEduVocLesson * rootLesson) { QList lessonsList; foreach(KEduVocContainer * child, rootLesson->childContainers()) { lessonsList << static_cast(child); lessonsList += flattenLessons(static_cast(child)); } return lessonsList; } QVariantList Lesson::childLessons(bool recursive) { if (recursive) return toVariantList (flattenLessons(m_lesson)); return toVariantList (m_lesson->childContainers()); } QVariantList Lesson::entries(bool recursive) const { return toVariantList (m_lesson->entries(boolToEnum(recursive))); } void Lesson::setEntries(QVariantList entries) { clearEntries(); foreach(const QVariant & ventry, entries) { QObject * obj = qvariant_cast (ventry); Expression * entry = dynamic_cast(obj); if (entry) m_lesson->appendEntry(entry->kEduVocExpression()); // qDebug() << entry->translationTexts(); } } QObject * Lesson::entry(int row, bool recursive) { return new Expression(m_lesson->entry(row, boolToEnum(recursive))); } int Lesson::entryCount(bool recursive) { return m_lesson->entryCount(boolToEnum(recursive)); } void Lesson::appendEntry(Expression * entry) { m_lesson->appendEntry(entry->kEduVocExpression()); } void Lesson::insertEntry(int index, Expression * entry) { m_lesson->insertEntry(index, entry->kEduVocExpression()); } void Lesson::removeEntry(QObject * entry) { /// @note parameter has to be QObject (tried with Expression * entry but didn't work) Expression * e = dynamic_cast(entry); if (e) { m_lesson->removeEntry(e->kEduVocExpression()); } else { qDebug() << "The entry given does not exist"; } } void Lesson::clearEntries() { int N = m_lesson->entryCount(KEduVocLesson::NotRecursive); for (int i = 0; i < N; i++) m_lesson->removeEntry(m_lesson->entry(0, KEduVocLesson::NotRecursive)); } QObject* Lesson::newEntry() { return new Expression(); } // QObject* Lesson::newEntry ( const QString & expression ) // { // return new Expression ( expression ); // } -QObject* Lesson::newEntry(QStringList translations) +QObject* Lesson::newEntry(const QStringList &translations) { return new Expression(translations); } -void Lesson::appendNewEntry(QStringList translations) +void Lesson::appendNewEntry(const QStringList &translations) { KEduVocExpression * expr = new KEduVocExpression(translations); m_lesson->appendEntry(expr); } QObject * Lesson::findChildLesson(const QString& name) { KEduVocContainer * container = findContainer(name); if (container) return new Lesson(container); qDebug() << "not found"; return 0; } } diff --git a/src/scripts/scripting/lesson.h b/src/scripts/scripting/lesson.h index 76c7110b..fc7b2e24 100644 --- a/src/scripts/scripting/lesson.h +++ b/src/scripts/scripting/lesson.h @@ -1,254 +1,254 @@ /*************************************************************************** Copyright 2008 Avgoustinos Kadis ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #ifndef SCRIPTINGSCRIPTOBJECTLESSON_H #define SCRIPTINGSCRIPTOBJECTLESSON_H #include #include "container.h" #include #include namespace Scripting { class Expression; /** * @class Lesson * @brief KEduVocLesson wrapping class for Kross scripts * * The Lesson class gives access to lesson properties, entries and child-lessons. The lesson properties documentation can be found in Container class as well as few function's documentation. * * The main way of accessing the lesson entries is with the entries() function which allows you to iterate through all the lesson entries (recursively also) and access their properties and modify them (see entries() function example code). For individual entry access use the entry(int) function. * * To add new entries to a lesson you can use the following ways: * - newEntry() or newEntry(QStringList) with appendEntry() or insertEntry() function * - appendNewEntry() function [easiest way] * * To remove an entry use the removeEntry() function * * @author Avgoustinos Kadis */ class Lesson : public Container { Q_OBJECT public: explicit Lesson(KEduVocLesson * lesson); explicit Lesson(KEduVocContainer * container); explicit Lesson(const QString& name); ~Lesson(); public slots: /** * Returns a list of all the entries of a lesson * @code * import Parley * entries = Parley.doc.rootLesson.entries(True) * for entry in entries * print entry.translationTexts() * @endcode * @param recursive If true, then will return recursively all the entries below this lesson * @return A list of Expression objects (entries) */ QVariantList entries(bool recursive = false) const; void setEntries(QVariantList entries); /** Returns the entry of the given @p row. If @p recursive is true then it considers all the entries of the sublessons too. */ QObject * entry(int row, bool recursive = false); /** Returns how many entries are in this lesson (or with sublessons if @p recursive is true) */ int entryCount(bool recursive = false); /** * Creates and returns a new Expression Object * @code * #how to add a new entry * import Parley * lesson = Parley.doc.findLesson("Lesson 2") * if lesson != None: * new_entry = lesson.newEntry() * new_entry.setTranslation(0,"day") * new_entry.setTranslation(0,"jour") * lesson.appendEntry(new_entry) * @endcode */ QObject* newEntry(); /** * Creates and returns a new Expression Object * @code * import Parley * lesson = Parley.doc.findLesson("Lesson 2") * if lesson != None: * new_entry = lesson.newEntry(["hello","bonjour"]) * lesson.appendEntry(new_entry) * @endcode * @param translations A list with the translations of this entry (must be in correct order) * @return A new Expression object */ - QObject* newEntry(QStringList translations); + QObject* newEntry(const QStringList &translations); /** * Appends an entry at the end of the lesson * @code * import Parley * lesson = Parley.doc.findLesson("Lesson 2") * if lesson != None: * new_entry = lesson.newEntry(["hello","bonjour"]) * lesson.appendEntry(new_entry) * @endcode * @param entry The entry to add the lesson */ void appendEntry(Expression * entry); /** * Creates and appends a new entry with the given @p translations * @code * #how to add a new entry with appendNewEntry() * import Parley * lesson = Parley.doc.rootLesson * lesson.appendNewEntry(["good morning","bonjour"]) * lesson.appendNewEntry(["play","jouer"]) * @endcode * @param translations A string list with the translations (in same order as their identifiers) */ - void appendNewEntry(QStringList translations); + void appendNewEntry(const QStringList &translations); /** * Insert an entry on a specific @p index * @param index Index where the entry will be added * @param entry The entry to add (can be created by newEntry() function) */ void insertEntry(int index, Expression * entry); /** * Removes an entry from this lesson * @code * #how to remove all the entries with the word "play" (from all lessons) * import Parley * for lesson in Parley.doc.allLessons(): * for entry in lesson.entries(): * for tr in entry.translations(): * if tr.text == "play": * lesson.remove(entry) * @endcode * @param entry A reference to the entry to remove */ void removeEntry(QObject * entry); /** * Removes all the lesson entries (not recursively) */ void clearEntries(); // @note this one doesn't work with the previous one (python doesn't know which one to call) /* * Creates and returns a new Expression Object * @param expression * @return A new Expression object */ // QObject* newEntry ( const QString & expression ); //child lesson public functions (just to change the names from "Container" to "Lesson") /** * Appends a @p child lesson under the current lesson */ void appendChildLesson(Lesson *child) { appendChildContainer(child); } /** * Inserts a child lesson (@p child) on the specified @p row */ void insertChildLesson(int row, Lesson *child) { insertChildContainer(row, child); } /* * Delete child lesson of the specified @p row */ // void deleteChildLesson ( int row ) { deleteChildContainer ( row ); } /** * Remove child lesson of the specified @p row */ void removeChildLesson(int row) { removeChildContainer(row); } /** * Return the child lesson with the corresponding @p row */ QObject *childLesson(int row) { return new Lesson(m_lesson->childContainer(row)); } /** * Retrieve a child container by its name * Returns 0 if no container is found * @param name lesson name * @return the child lesson */ QObject *childLesson(const QString& name) { return new Lesson(m_lesson->childContainer(name)); } /** * Returns a list of all the child lessons * @code * #how to access the all the lessons * import Parley * for lesson in Parley.doc.rootLesson.childLessons(True): * print lesson.name * @endcode * @param recursive If true, then will return the child lessons recursively * @return A List with Lesson objects (child lessons) */ QVariantList childLessons(bool recursive = false); /** * Searches through all the child lessons (recursively) and returns the first lesson the specified @p name * @code * #how to search for a lesson * import Parley * lesson = Parley.doc.rootLesson.findChildLesson("Lesson 5") * if lesson != None: * print "found" * print lesson.name * else: * print "not found" * @endcode * @param name Name of the lesson to look for * @return A reference to a lesson if found. 0 otherwise */ QObject * findChildLesson(const QString& name); /** * Returns how many child lessons exist under this lesson */ int childLessonCount() const { return childContainerCount(); } private: KEduVocLesson* m_lesson; }; } #endif diff --git a/src/scripts/scripting/parley.cpp b/src/scripts/scripting/parley.cpp index f11d735c..9c39b511 100644 --- a/src/scripts/scripting/parley.cpp +++ b/src/scripts/scripting/parley.cpp @@ -1,152 +1,152 @@ /*************************************************************************** Copyright 2008 Avgoustinos Kadis ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #include "parley.h" #include "editor/editor.h" #include "vocabularymodel.h" #include "vocabularyview.h" #include "../scriptmanager.h" #include "../translator.h" #include "document.h" #include "lesson.h" #include "expression.h" #include "translation.h" #include #include #include using namespace Editor; namespace Scripting { Parley::Parley(EditorWindow * editor) : QObject(), m_editor(editor) { m_translator = new Translator(this); //parameter has to be cause it's used by Translator to access callTranslateWord m_doc = new Document(m_editor->m_mainWindow->parleyDocument()->document()); } Parley::~Parley() { delete m_translator; delete m_doc; } void Parley::callTranslateWord(const QString & word, const QString& fromLanguage, const QString& toLanguage) { emit translationStarted(word, fromLanguage, toLanguage); emit translateWord(word, fromLanguage, toLanguage); emit translationFinished(word, fromLanguage, toLanguage); } -void Parley::addTranslation(QString word, QString fromLanguage, QString toLanguage, QString translation) +void Parley::addTranslation(const QString &word, const QString &fromLanguage, const QString &toLanguage, const QString &translation) { if (m_translator) m_translator->addTranslation(word, fromLanguage, toLanguage, translation); } QStringList Parley::locales() { /// @todo Change it into a QMap property (Parley.languageCodes) return QLocale().uiLanguages(); } -QString Parley::localeName(QString locale) +QString Parley::localeName(const QString &locale) { return QLocale( locale ).nativeLanguageName( ); } -void Parley::open(QString filename) +void Parley::open(const QString &filename) { QUrl url( QUrl::fromLocalFile(filename) ); qDebug() << url; m_editor->m_mainWindow->parleyDocument()->open(url); } QObject* Parley::activeLesson() { return new Lesson(m_editor->m_vocabularyModel->lesson()); } QVariantList Parley::selectedEntries() { QVariantList entries; //get selected indexes and active lesson QModelIndexList indexes = m_editor->m_vocabularyView->getSelectedIndexes(); //get the unique selected entries QSet kentries; foreach(const QModelIndex & index, indexes) { // qDebug() << index.row() << index.data(Qt::DisplayRole); KEduVocExpression * expr = qvariant_cast (index.data(VocabularyModel::EntryRole)); kentries << expr; } //convert them to Expression objects and add them to the QVariantList foreach(KEduVocExpression * expr, kentries) { // Expression entry(expr); // qDebug() << entry.translationTexts(); QObject * obj = new Expression(expr); entries << qVariantFromValue(obj); } return entries; } QVariantList Parley::selectedTranslations() { QVariantList translations; //get selected indexes and active lesson QModelIndexList indexes = m_editor->m_vocabularyView->getSelectedIndexes(); //get the unique selected entries QSet ktranslations; // const QModelIndex &index; foreach(const QModelIndex & index, indexes) { if (VocabularyModel::columnType(index.column()) == VocabularyModel::Translation) { KEduVocExpression * expr = qvariant_cast (index.data(VocabularyModel::EntryRole)); ktranslations << expr->translation(VocabularyModel::translation(index.column())); } // qDebug() << index.row() << index.data(Qt::DisplayRole); } //convert them to Expression objects and add them to the QVariantList foreach(KEduVocTranslation * tr, ktranslations) { // Translation transltion(tr); // qDebug() << entry.translationTexts(); QObject * obj = new Translation(tr); translations << qVariantFromValue(obj); } return translations; } QObject * Scripting::Parley::newAction(const QString & name, const QString& text) { //create new action QAction* action = new QAction(text, m_editor); m_editor->m_scriptManager->addScriptAction(name, action); return action; } } diff --git a/src/scripts/scripting/parley.h b/src/scripts/scripting/parley.h index b4709d08..e01a3ff6 100644 --- a/src/scripts/scripting/parley.h +++ b/src/scripts/scripting/parley.h @@ -1,415 +1,415 @@ /*************************************************************************** Copyright 2008 Avgoustinos Kadis ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #ifndef SCRIPTOBJECTPARLEY_H #define SCRIPTOBJECTPARLEY_H #include "document.h" #include #include #include #include #include #include namespace Editor { class EditorWindow; } class Translator; /** * @namespace Scripting * @brief Contains all the classes exposed to Kross scripts. * * Main entry point is the Scripting::Parley class which allows us to access all the other Scripting classes (see code below). * * Class Hierarchy: * * - Parley * - Document * - Lesson (inherits Container) * - Expression (known as Entry in functions) * - Translation (inherits Text) * - Identifier * *

How to create a new %Parley script (full example)

* * Each %Parley script must be accompanied by a .desktop file, both put in the plugins folder in parley data directory (usually in /usr/share/apps/parley/plugins/). In this example the desktop file is "example.desktop" and the script file is "example.py". * * The desktop file provides information about the script's functionality, author and specifies the script file that implements it. This information will appear in the Scripts Manager (Scripts->Script Manager in main menu) and the user will be able to enable/disable the script. If the script is enabled then it'll be loaded every time Parley starts up. * * Content of example.desktop (/usr/share/apps/parley/plugins/example.desktop) * @code [Desktop Entry] Encoding=UTF-8 Icon=mypluginicon Type=Service ServiceTypes=KPluginInfo Name=Example Parley Script Comment=This Script offers two actions: 1) Move to new lesson 2) Mark as known for the Scripts menu Script=example.py X-KDE-PluginInfo-Author=Avgoustinos Kadis X-KDE-PluginInfo-Email=avgoustinos.kadis@kdemail.net X-KDE-PluginInfo-Name=parley_example_script X-KDE-PluginInfo-Version=1.1 X-KDE-PluginInfo-Website=http://edu.kde.org/parley X-KDE-PluginInfo-Category=examples X-KDE-PluginInfo-License=GPL X-KDE-PluginInfo-EnabledByDefault=true @endcode * * The script file will contain the functions (script functionality) and some code for creating an action for the Scripts menu. In the example below, the functions are moveSelectedToNewLesson() and markAsKnown() and they are called by the two actions that are added to the scripts menu (action1 and action2). * * When the script file is loaded all the global code (outside of any function) is executed. This way we can register the Scripts menu actions and connect them with script functions (see example below for how to do this). * * Another way to have a function called is by connecting it to a %Parley signal (see Parley::translateWord() and the example in Detailed Description of the Parley class). * * Content of example.py (/usr/share/apps/parley/plugins/example.py) @code #!/usr/bin/env kross import Parley #FUNCTIONS #moves selected entries to a new lesson def moveSelectedToNewLesson(): selected_entries = Parley.selectedEntries() if len(selected_entries) > 0: newlesson = Parley.doc.appendNewLesson("New Lesson") for entry in selected_entries: newlesson.appendEntry(entry) #marks the selected translations as known (grade 7) def markAsKnown(): for tr in Parley.selectedTranslations(): tr.grade = 7 #SCRIPT MENU #create a new action for the Scripts menu (action1) action1 = Parley.newAction("example_action1","Move to new lesson") action1.statusTip="Moves the selected rows to a new lesson" Parley.connect(action1,"triggered()",moveSelectedToNewLesson) #create a new action for the Scripts menu (action2) action2 = Parley.newAction("example_action2","Mark as known (highest level)") action2.statusTip="Sets the confidence level selected translations to 7 (highest level)" Parley.connect(action2,"triggered()",markAsKnown) @endcode * * After creating the Script action and being able to call a function you can start adding your own code, using the documentation provided for the scripting classes and by seeing other examples. * * For debugging use the standard output and observed it in the terminal. * */ namespace Scripting { /** * @class Parley * @brief Parley scripting class (main entry point of a %Parley Kross script) * * Parley class is the main entry point of Parley scripting classes. Through it you can access the Document class (Parley.doc or Parley.document) which provides functionality for viewing/modifying a %Parley document (%KEduVocDocument), that means access lessons, entries, document languages etc. * * The Parley class has to do more with the active %Parley application. Here it follows a list of possible usages of Parley class: * * - Add a new Action to the script menu (see Parley::newAction() function) * - Add a new translation script (see Parley::translateWord() signal) * - Have direct access to the active lesson (see Parley::activeLesson property) * - Have access to various enumerations (see Parley::Number, Parley::Case, Parley::Person, Parley::Gender and Parley::Definiteness enumerations) * - Create a new %Parley %Document (see Parley::newDocument() function) * * Signals and Slots: To connect a script function (slot) to a signal you just define a function with the same name as the signal or use the Parley.connect function: * @code * #how to connect a function to a signal (example with Parley::translateWord() signal) * def translateFromInternet(word,fromLang,toLang): * print "Translating from Internet!!.." * * Parley.connect("translateWord(const QString &,const QString &,const QString &)",translateFromInternet) * @endcode * * @author Avgoustinos Kadis */ class Parley : public QObject { Q_OBJECT /// Read-only property of the active document Q_PROPERTY(QObject * document READ getDocument) /// Abreviation of document property (same as Parley.document) Q_PROPERTY(QObject * doc READ getDocument) /// Currently active lesson Q_PROPERTY(QObject * activeLesson READ activeLesson) // Q_ENUMS ( Number Case Person Gender Definiteness ) Q_ENUMS(Flags) public: enum Flags { // This is used for both empty flags and to denote no flags of the correct type were set. NoInformation = 0x0, // Gender Masculine = 0x1, Feminine = 0x2, Neuter = 0x4, // Plurality Singular = 0x10, Dual = 0x20, Plural = 0x40, // Part of Speech Verb = 0x100, Noun = 0x200, Pronoun = 0x400, Adjective = 0x800, Adverb = 0x1000, Article = 0x2000, Conjunction = 0x4000, // Person First = 0x10000, Second = 0x20000, Third = 0x40000, // Declension Case Nominative = 0x80000, Genitive = 0x100000, Dative = 0x200000, Accusative = 0x400000, Ablative = 0x800000, Locative = 0x1000000, Vocative = 0x2000000, // Other assorted flags Definite = 0x4000000, // The article is definite Indefinite = 0x8000000, // The article is indefinite Regular = 0x10000000, Irregular = 0x20000000 }; explicit Parley(Editor::EditorWindow * editor); ~Parley(); /* * Emits translateWord signal so the script function connected to it translate the @p word * @param word Word to translate * @param fromLanguage The language of @p word to translate from * @param toLanguage The language you want to translate to */ void callTranslateWord(const QString & word, const QString& fromLanguage, const QString& toLanguage); //sets the translator object // void setTranslator ( Translator* translator ) { m_translator = translator; } Translator * translator() { return m_translator; } //Returns the active document QObject* getDocument() { return m_doc; } //Returns the active lesson QObject* activeLesson(); public Q_SLOTS: QStringList dataDirs() { return QStandardPaths::standardLocations(QStandardPaths::DataLocation); } QStringList pluginDirs() { QStringList basedirs(QStandardPaths::standardLocations(QStandardPaths::DataLocation)); QStringList ret; foreach ( const QString dir , basedirs){ ret << (dir + "/plugins"); } return ret; } /** Returns a list of Expression objects (the selected entries of the active lesson) */ QVariantList selectedEntries(); /** Returns a list of Translation objects (the selected translations of the active lesson) */ QVariantList selectedTranslations(); /** * Adds the found @p translation of the @p word from language @p fromLanguage to language @p toLanguage to %Parley translations to be used for translating lesson entries (or anything else). This function is ment to be used by scripts to add a translation of a word by parsing either online or offline dictionaries. * * @code * #example usage of addTranslation function * import Parley * #function called by Parley whenever a translation of a word is needed * def translateWord(word,fromLang,toLang): * <> * Parley.addTranslation(word,fromLang,toLang,foundWord) * <> * @endcode * * @param word Translated word * @param fromLanguage From language * @param toLanguage To language * @param translation %Translation of word */ - void addTranslation(QString word, QString fromLanguage, QString toLanguage, QString translation); + void addTranslation(const QString &word, const QString &fromLanguage, const QString &toLanguage, const QString &translation); /** * Returns a list of all available locales (to be used by the scripts) * @return */ QStringList locales(); /** * Gives the language name of the given @p locale * @param locale Language locale * @return Language name */ - QString localeName(QString locale); + QString localeName(const QString &locale); /// @todo Make this function working (not very important function) /* * Open the Parley Document @p file * Usage: * @code * import Parley * Parley.open("Vocab/MyVocab.kvtml") * @endcode * @param file Parley Document file path (ex. /home/kde-user/MyVocab.kvtml) */ - void open(QString filename); + void open(const QString &filename); /** * Creates a new document and returns a reference to it * * @code * #how to create a new document, add lessons, add entries and save it to a kvtml file * import Parley * * #create new document * doc = Parley.newDocument() * doc.title = "New document" * * #set identifiers * doc.appendNewIdentifier("English","en_US") * doc.appendNewIdentifier("French","fr") * * #lessons * l1 = doc.newLesson("Lesson1") * doc.rootLesson.appendChildLesson(l1) * * #add a new entry (first way) * e = l1.newEntry() * e.setTranslation(0,"dog") * e.setTranslation(1,"chien") * l1.appendEntry(e) * * #add a new entry (second way) * ee = l1.newEntry(["glass","verre"]) * l1.appendEntry(ee) * #third way * ee = l1.appendNewEntry(["book","livre"]) * * #add a new lesson (fast way) * l2 = doc.appendNewLesson("Lesson 2") * * #add a new child lesson under "Lesson 2" * l3 = doc.appendNewLesson("Lesson 3",l2) * * #add a new entry (third way) * l2.appendNewEntry(["I","je"]); * l3.appendNewEntry(["good morning","bonjour"]) * * #save document * doc.saveAs("/home/kde-devel/test_new_document.kvtml") * @endcode * * @return A Document object, the newly created lesson */ QObject * newDocument() { return new Document(); } /** * Creates and adds to the Scripts menu a new QAction (see QAction documentation) * * @code * #how to add two new Scripts menu entries * import Parley * * def convertLessonToPDF(): * print "Converting lesson to PDF.." * * def convertLessonToHTML(): * print "Converting lesson to HTML.." * * #one way of creating a new action * newaction_pdf = Parley.newAction("convert_lesson_pdf") * newaction_pdf.text="Convert Lesson to PDF" * Parley.connect(newaction_pdf,"triggered()",convertLessonToPDF) * * #second way of creating a new action (short) * newaction_html = Parley.newAction("convert_lesson_html","Convert Lesson to HTML") * Parley.connect(newaction_html,"triggered()",convertLessonToHTML) * @endcode * * @param name Unique action name * @param text Action's text (what text appears in the scripts menu) * @return A reference to a QAction object (accessible by scripts) */ QObject * newAction(const QString & name, const QString & text = QString()); Q_SIGNALS: /** * Slots (script functions) connected to this signal are called when a translation of @p word is requested. Note that a script function with the same name as a signal will be automatically connected to that signal when the script is activated. * * @code * #example usage of translateWord signal * import Parley * #function called by Parley whenever a translation of a word is needed * def translateWord(word,fromLang,toLang): * <> * Parley.addTranslation(word,fromLang,toLang,foundWord) * <> * @endcode * * @param word Word to translate * @param fromLanguage The language of @p word to translate from * @param toLanguage The language you want to translate to */ void translateWord(const QString & word, const QString& fromLanguage, const QString& toLanguage); /* Emits when the translation of a word is finished (from all the scripts) [not to be used by scripts] */ void translationFinished(const QString & word, const QString& fromLanguage, const QString& toLanguage); /* Emits when the translation of a word starts [not to be used by scripts] */ void translationStarted(const QString & word, const QString& fromLanguage, const QString& toLanguage); private: Translator* m_translator; Document* m_doc; Editor::EditorWindow * m_editor; }; } #endif diff --git a/src/scripts/scriptmanager.cpp b/src/scripts/scriptmanager.cpp index 91731518..d475b2c8 100644 --- a/src/scripts/scriptmanager.cpp +++ b/src/scripts/scriptmanager.cpp @@ -1,185 +1,185 @@ /*************************************************************************** Copyright 2008 Avgoustinos Kadis ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #include "scriptmanager.h" #include #include #include #include #include #include #include #include #include #include #include #include using namespace Editor; ScriptManager::ScriptManager(EditorWindow * editor) : m_editor(editor) { //add Scripting::Parley m_scriptingParley = new Scripting::Parley(editor); addObject(m_scriptingParley, QStringLiteral("Parley")); } ScriptManager::~ScriptManager() { } QStringList ScriptManager::getDesktopFiles() { // QStringList scriptsAvailable; QStringList dirs( QStandardPaths::locateAll( QStandardPaths::DataLocation, QStringLiteral("plugins"), QStandardPaths::LocateDirectory ) ); QStringList filenames; foreach ( const QString dir, dirs ) { foreach ( const QString filename, QDir( dir ).entryList(QDir::Files) ) { if ( filename.endsWith(QLatin1String(".desktop") ) ) { filenames << dir + '/' + filename; } } } return filenames; } QMap ScriptManager::categories() { QMap categories; categories[QStringLiteral("translation")] = QStringLiteral("Translation"); return categories; } -QString ScriptManager::getScriptEntry(QString desktopFile) +QString ScriptManager::getScriptEntry(const QString &desktopFile) { //open it as a raw configuration file and read the script entry KConfig scriptconfig(desktopFile, KConfig::SimpleConfig); KConfigGroup group = scriptconfig.group("Desktop Entry"); return group.readEntry("Script"); } -QString ScriptManager::getScriptFileName(QString desktopFile) +QString ScriptManager::getScriptFileName(const QString &desktopFile) { QFileInfo desktopFileInfo(desktopFile); return desktopFileInfo.absolutePath() + '/' + ScriptManager::getScriptEntry(desktopFile); } QStringList ScriptManager::enabledScripts() { QStringList enabledScripts; // Open parleyrc to read the state of the plugins (enabled/disabled) KConfigGroup cfg(KSharedConfig::openConfig(QStringLiteral("parleyrc")), "Plugins"); // Get list of KPluginInfo for each of the desktop files found QList pluginsInfoList = KPluginInfo::fromFiles(getDesktopFiles()); // Find which plugins are enabled and add them to enabledScripts list KPluginInfo inf; foreach(inf, pluginsInfoList) { inf.load(cfg); if (inf.isPluginEnabled()) enabledScripts.push_back(inf.entryPath()); // qDebug() << inf.name() << inf.isPluginEnabled() << inf.pluginName(); } return enabledScripts; } -void ScriptManager::disablePlugin(QString desktopFile) +void ScriptManager::disablePlugin(const QString &desktopFile) { KConfigGroup cfg(KSharedConfig::openConfig(QStringLiteral("parleyrc")), "Plugins"); KPluginInfo inf(desktopFile); //load parleyrc enabled value inf.load(cfg); inf.setPluginEnabled(false); //save enabled=true in parleyrc inf.save(cfg); } void ScriptManager::loadScripts() { QStringList scripts = enabledScripts(); QStringList failed; QStringList errorDetails; foreach(const QString & script, scripts) { //create a new Script and add it to the m_scripts list Script * s = new Script(getScriptFileName(script)); s->addObjects(m_scriptObjects); s->activate(); m_scripts.push_back(s); if (!s->isActivated()) { failed << getScriptFileName(script); //TODO: real name? errorDetails << s->errorMessage(); disablePlugin(script); } } //inform with a message box when a script could not be activated if (!failed.empty()) { QString errorMessage = "

" + i18np("A script could not be activated and has been disabled.", "%1 scripts could not be activated and have been disabled.", failed.count()) + ' ' + i18n("This probably means that there are errors in the script or that the required packages are not installed.") + "

"; errorMessage += "
  • " + failed.join(QStringLiteral("
  • ")) + "
"; KMessageBox::detailedError(m_editor, errorMessage, errorDetails.join(QStringLiteral("
")), i18n("Script Activation")); } } void ScriptManager::addObject(QObject * obj, const QString & name) { m_scriptObjects[name] = obj; } void ScriptManager::reloadScripts() { //deactivate (delete) all the active scripts foreach(Script * s, m_scripts) { if (s) delete s; } m_scripts.clear(); //reload the scripts menu m_editor->unplugActionList(QStringLiteral("scripts_actionlist")); m_scriptActions.clear(); m_editor->plugActionList(QStringLiteral("scripts_actionlist"), m_scriptActions); //load all the enabled scripts loadScripts(); } void ScriptManager::addScriptAction(const QString & name, QAction * action) { //unplug action list (orelse it will add twice the same entries m_editor->unplugActionList(QStringLiteral("scripts_actionlist")); //add to action collection m_editor->actionCollection()->addAction(name, action); //add it to actions menu list m_editor->m_scriptManager->m_scriptActions.push_back(action); //plug the action list m_editor->plugActionList(QStringLiteral("scripts_actionlist"), m_scriptActions); } diff --git a/src/scripts/scriptmanager.h b/src/scripts/scriptmanager.h index cae46f95..1fa0b291 100644 --- a/src/scripts/scriptmanager.h +++ b/src/scripts/scriptmanager.h @@ -1,125 +1,125 @@ /*************************************************************************** Copyright 2008 Avgoustinos Kadis ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #ifndef SCRIPTMANAGER_H #define SCRIPTMANAGER_H #include "script.h" #include "editor/editor.h" #include /** * This class finds the scripts installed in the application directory and manages loading and unloading of the scripts. For each script an instance of Script class is created. * * @author Avgoustinos Kadis */ class ScriptManager : public QObject { public: explicit ScriptManager(Editor::EditorWindow * editor); ~ScriptManager(); /** * Finds all the available desktop files in {PARLEY_DATA_FOLDER}/plugins * * @return The list of desktop filenames available for parley */ static QStringList getDesktopFiles(); /** * Returns a QMap (from from categories codenames to categories display label) * to be used in KPluginSelector (ScriptDialog) for displaying the various * categories * * @note this function is not used later on (categories are disabled) * * @return the QMap described above */ static QMap categories(); /** * Parses the desktop @p desktopFile given and returns the value of "Script" entry. * * @param desktopFile The .desktop file that will get the value from * @return The value of "Script" entry. Empty string of no "Script" entry is found */ - static QString getScriptEntry(QString desktopFile); + static QString getScriptEntry(const QString &desktopFile); /** * Returns the full path to the script name given in the @p desktopFile. * * @param desktopFile The desktop file for the parley plugin * @return The full-path to the script */ - QString getScriptFileName(QString desktopFile); + QString getScriptFileName(const QString &desktopFile); /** * Returns a list of filenames (full path) of enabled scripts */ QStringList enabledScripts(); /** * Modify the parleyrc configuration so it disables the @p dektopFile plugin. * This function is to be used when the plugin is invalid (wrong script name, * incorrect desktop file etc) * * @param desktopFile */ - void disablePlugin(QString desktopFile); + void disablePlugin(const QString &desktopFile); /** * Loads (activates) all the available scripts and notifies the user if any * script was not activated (due to errors in the script) */ void loadScripts(); /** * Adds a QObject as a module for the script * @param obj The QObject to be added to the script * @param name The name of the object as it will appear in the script */ void addObject(QObject * obj, const QString & name); /** * Reloads all the scripts */ void reloadScripts(); /** * Add a QAction to the Scripts menu * @param name The action name * @param action QAction to be added */ void addScriptAction(const QString & name, QAction * action); /** returns the Translator object the Scripting::Parley */ Translator * translator() { return m_scriptingParley->translator(); } private: Editor::EditorWindow * m_editor; QList m_scripts; QMap m_scriptObjects; QList m_scriptActions; ///script objects (objects that will be used from inside the scripts) Scripting::Parley* m_scriptingParley; }; #endif diff --git a/src/scripts/translator.cpp b/src/scripts/translator.cpp index e6bf52c4..dcabc5d6 100644 --- a/src/scripts/translator.cpp +++ b/src/scripts/translator.cpp @@ -1,64 +1,64 @@ /*************************************************************************** Copyright 2008 Avgoustinos Kadis ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #include "translator.h" #include "scripting/parley.h" #include Translator::Translator() : m_parent(nullptr) { } Translator::Translator(QObject * parent) : m_parent(parent) { } Translator::~Translator() { } -void Translator::addTranslation(QString word, QString fromLanguage, QString toLanguage, QString translation) +void Translator::addTranslation(const QString &word, const QString &fromLanguage, const QString &toLanguage, const QString &translation) { if (word.trimmed() == QLatin1String("")) return; QString t = word + fromLanguage + toLanguage; qDebug() << "Translation for " << word << "in cache: " << m_translations.contains(t); if (!m_translations.contains(t)) { m_translations[t] = new QSet(); } m_translations[t]->insert(translation.simplified()); } -QSet* Translator::getTranslation(QString word, QString fromLanguage, QString toLanguage) +QSet* Translator::getTranslation(const QString &word, const QString &fromLanguage, const QString &toLanguage) { if (word.isEmpty() || fromLanguage.isEmpty() || toLanguage.isEmpty()) return 0; QString t = word + fromLanguage + toLanguage; qDebug() << "Fetch translation " << word << "(" << fromLanguage << "to" << toLanguage << ")" << "already in cache:" << m_translations.contains(t); if (!m_translations.contains(t)) { Scripting::Parley * p = dynamic_cast(m_parent); if (p) { p->callTranslateWord(word, fromLanguage, toLanguage); } } if (m_translations.contains(t)) return m_translations.value(t); else return 0; } diff --git a/src/scripts/translator.h b/src/scripts/translator.h index aa64f886..4215cd70 100644 --- a/src/scripts/translator.h +++ b/src/scripts/translator.h @@ -1,107 +1,107 @@ /*************************************************************************** Copyright 2008 Avgoustinos Kadis ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #ifndef TRANSLATOR_H #define TRANSLATOR_H #include // #include #include /*class Translation { public: QString word; QString fromLanguage; QString toLanguage; Translation () { word = ""; fromLanguage = ""; toLanguage = ""; } Translation ( QString pword, QString pfromLanguage, QString ptoLanguage ) { word = pword; fromLanguage = pfromLanguage; toLanguage = ptoLanguage; } void operator=(const Translation &t1) { word = t1.word; fromLanguage = t1.fromLanguage; toLanguage = t1.toLanguage; } // inline bool operator<(const Translation &t2) { // if ( word != t2.word ) // return word < t2.word; // if ( fromLanguage != t2.fromLanguage ) // return fromLanguage < t2.fromLanguage; // return toLanguage < t2.toLanguage; // } };*/ // inline bool operator<( const Translation &t1, const Translation &t2 ) // { // if ( t1.word != t2.word ) // return t1.word < t2.word; // if ( t1.fromLanguage != t2.fromLanguage ) // return t1.fromLanguage < t2.fromLanguage; // return t1.toLanguage < t2.toLanguage; // } #include "../parleymainwindow.h" /** Keeps the translated words @author Avgoustinos Kadis */ class Translator { public: Translator(); explicit Translator(QObject * parent); ~Translator(); /** * Stores the translation of @p word from language @p fromLanguage, to language @p toLanguage. * @param word word that was translated * @param fromLanguage language of @p word * @param toLanguage language of @p translation * @param translation translation of @p word */ - void addTranslation(QString word, QString fromLanguage, QString toLanguage, QString translation); + void addTranslation(const QString &word, const QString &fromLanguage, const QString &toLanguage, const QString &translation); /** * Returns a QStringList with all the translations of @p word from @p fromLanguage to @p toLanguage. * This function will call the translateWord function of the translation scripts if this word * wasn't translated before. * @param word * @param fromLanguage * @param toLanguage * @return QStringList with the translations (or an empty QStringList if no translations found) */ - QSet* getTranslation(QString word, QString fromLanguage, QString toLanguage); + QSet* getTranslation(const QString &word, const QString &fromLanguage, const QString &toLanguage); private: QMap*> m_translations; QObject * m_parent; }; #endif