summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVlad Voicu <vladvoic@gmail.com>2011-11-28 16:37:32 (GMT)
committerVlad Voicu <vladvoic@gmail.com>2013-03-15 09:21:52 (GMT)
commit2061b06eccca67595c50edd81c44c5b961bf108b (patch)
tree7fdc9e4cc80a9d8ddbe5364a531ef3449f72ab2b /Swift/QtUI
parenta069a0df0f51a948a86e34d99f952a33eecd97ba (diff)
downloadswift-2061b06eccca67595c50edd81c44c5b961bf108b.zip
swift-2061b06eccca67595c50edd81c44c5b961bf108b.tar.bz2
Spell checker implementation using Hunspell
Change-Id: Ia15b6532edf6eef7c45bdfb273e77f65ce998f13 License: This patch is BSD-licensed, see Documentation/Licenses/BSD-simplified.txt for details
Diffstat (limited to 'Swift/QtUI')
-rw-r--r--Swift/QtUI/QtChatWindow.cpp2
-rw-r--r--Swift/QtUI/QtJoinMUCWindow.ui6
-rw-r--r--Swift/QtUI/QtSpellCheckerWindow.cpp104
-rw-r--r--Swift/QtUI/QtSpellCheckerWindow.h33
-rw-r--r--Swift/QtUI/QtSpellCheckerWindow.ui87
-rw-r--r--Swift/QtUI/QtTextEdit.cpp169
-rw-r--r--Swift/QtUI/QtTextEdit.h28
-rw-r--r--Swift/QtUI/SConscript4
8 files changed, 425 insertions, 8 deletions
diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp
index 7f27cb6..11e64ab 100644
--- a/Swift/QtUI/QtChatWindow.cpp
+++ b/Swift/QtUI/QtChatWindow.cpp
@@ -152,7 +152,7 @@ QtChatWindow::QtChatWindow(const QString &contact, QtChatTheme* theme, UIEventSt
QHBoxLayout* inputBarLayout = new QHBoxLayout();
inputBarLayout->setContentsMargins(0,0,0,0);
inputBarLayout->setSpacing(2);
- input_ = new QtTextEdit(this);
+ input_ = new QtTextEdit(settings_, this);
input_->setAcceptRichText(false);
inputBarLayout->addWidget(midBar_);
inputBarLayout->addWidget(input_);
diff --git a/Swift/QtUI/QtJoinMUCWindow.ui b/Swift/QtUI/QtJoinMUCWindow.ui
index 5a69292..9225f6f 100644
--- a/Swift/QtUI/QtJoinMUCWindow.ui
+++ b/Swift/QtUI/QtJoinMUCWindow.ui
@@ -43,9 +43,6 @@
</property>
</widget>
</item>
- <item row="1" column="1" colspan="2">
- <widget class="QLineEdit" name="nickName"/>
- </item>
<item row="0" column="1">
<widget class="QLineEdit" name="room">
<property name="text">
@@ -63,6 +60,9 @@
<item row="2" column="1">
<widget class="QLineEdit" name="password"/>
</item>
+ <item row="1" column="1" colspan="2">
+ <widget class="QLineEdit" name="nickName"/>
+ </item>
</layout>
</item>
<item>
diff --git a/Swift/QtUI/QtSpellCheckerWindow.cpp b/Swift/QtUI/QtSpellCheckerWindow.cpp
new file mode 100644
index 0000000..e2c5b0d
--- /dev/null
+++ b/Swift/QtUI/QtSpellCheckerWindow.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2011 Vlad Voicu
+ * Licensed under the Simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "Swift/QtUI/QtSpellCheckerWindow.h"
+
+#include <Swift/Controllers/Settings/SettingsProvider.h>
+#include <Swift/Controllers/SettingConstants.h>
+#include <Swift/QtUI/QtUISettingConstants.h>
+#include <Swift/QtUI/QtSwiftUtil.h>
+
+#include <QCoreApplication>
+#include <QFileDialog>
+#include <QDir>
+#include <QStringList>
+
+namespace Swift {
+
+QtSpellCheckerWindow::QtSpellCheckerWindow(SettingsProvider* settings, QWidget* parent) : QDialog(parent) {
+ settings_ = settings;
+ ui_.setupUi(this);
+ connect(ui_.spellChecker, SIGNAL(toggled(bool)), this, SLOT(handleChecker(bool)));
+ connect(ui_.cancel, SIGNAL(clicked()), this, SLOT(handleCancel()));
+ connect(ui_.apply, SIGNAL(clicked()), this, SLOT(handleApply()));
+ connect(ui_.pathButton, SIGNAL(clicked()), this, SLOT(handlePathButton()));
+ setFromSettings();
+}
+
+void QtSpellCheckerWindow::setFromSettings() {
+ ui_.spellChecker->setChecked(settings_->getSetting(SettingConstants::SPELL_CHECKER));
+ ui_.pathContent->setText(P2QSTRING(settings_->getSetting(SettingConstants::DICT_PATH)));
+ ui_.currentLanguageValue->setText(P2QSTRING(settings_->getSetting(SettingConstants::DICT_FILE)));
+ std::string currentPath = settings_->getSetting(SettingConstants::DICT_PATH);
+ QString filename = "*.dic";
+ QDir dictDirectory = QDir(P2QSTRING(currentPath));
+ QStringList files = dictDirectory.entryList(QStringList(filename), QDir::Files);
+ showFiles(files);
+ setEnabled(settings_->getSetting(SettingConstants::SPELL_CHECKER));
+}
+
+void QtSpellCheckerWindow::handleChecker(bool state) {
+ setEnabled(state);
+}
+
+void QtSpellCheckerWindow::setEnabled(bool state) {
+ ui_.pathContent->setEnabled(state);
+ ui_.languageView->setEnabled(state);
+ ui_.pathButton->setEnabled(state);
+ ui_.pathLabel->setEnabled(state);
+ ui_.currentLanguage->setEnabled(state);
+ ui_.currentLanguageValue->setEnabled(state);
+ ui_.language->setEnabled(state);
+}
+
+void QtSpellCheckerWindow::handleApply() {
+ settings_->storeSetting(SettingConstants::SPELL_CHECKER, ui_.spellChecker->isChecked());
+ QList<QListWidgetItem* > selectedLanguage = ui_.languageView->selectedItems();
+ if (!selectedLanguage.empty()) {
+ settings_->storeSetting(SettingConstants::DICT_FILE, Q2PSTRING((selectedLanguage.first())->text()));
+ }
+ this->done(0);
+}
+
+void QtSpellCheckerWindow::handleCancel() {
+ this->done(0);
+}
+
+void QtSpellCheckerWindow::handlePathButton() {
+ std::string currentPath = settings_->getSetting(SettingConstants::DICT_PATH);
+ QString dirpath = QFileDialog::getExistingDirectory(this, tr("Dictionary Path"), P2QSTRING(currentPath));
+ if (dirpath != P2QSTRING(currentPath)) {
+ ui_.languageView->clear();
+ settings_->storeSetting(SettingConstants::DICT_FILE, "");
+ ui_.currentLanguageValue->setText(" ");
+ }
+ if (!dirpath.isEmpty()) {
+ if (!dirpath.endsWith("/")) {
+ dirpath.append("/");
+ }
+ settings_->storeSetting(SettingConstants::DICT_PATH, Q2PSTRING(dirpath));
+ QDir dictDirectory = QDir(dirpath);
+ ui_.pathContent->setText(dirpath);
+ QString filename = "*.dic";
+ QStringList files = dictDirectory.entryList(QStringList(filename), QDir::Files);
+ showFiles(files);
+ }
+}
+
+void QtSpellCheckerWindow::handlePersonalPathButton() {
+ std::string currentPath = settings_->getSetting(SettingConstants::PERSONAL_DICT_PATH);
+ QString filename = QFileDialog::getOpenFileName(this, tr("Select Personal Dictionary"), P2QSTRING(currentPath), tr("(*.dic"));
+ settings_->storeSetting(SettingConstants::PERSONAL_DICT_PATH, Q2PSTRING(filename));
+}
+
+void QtSpellCheckerWindow::showFiles(const QStringList& files) {
+ ui_.languageView->clear();
+ for (int i = 0; i < files.size(); ++i) {
+ ui_.languageView->insertItem(i, files[i]);
+ }
+}
+
+}
diff --git a/Swift/QtUI/QtSpellCheckerWindow.h b/Swift/QtUI/QtSpellCheckerWindow.h
new file mode 100644
index 0000000..ad94907
--- /dev/null
+++ b/Swift/QtUI/QtSpellCheckerWindow.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2011 Vlad Voicu
+ * Licensed under the Simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include "ui_QtSpellCheckerWindow.h"
+
+#include <QDialog>
+
+namespace Swift {
+ class SettingsProvider;
+ class QtSpellCheckerWindow : public QDialog, protected Ui::QtSpellCheckerWindow {
+ Q_OBJECT
+ public:
+ QtSpellCheckerWindow(SettingsProvider* settings, QWidget* parent = NULL);
+ public slots:
+ void handleChecker(bool state);
+ void handleCancel();
+ void handlePathButton();
+ void handlePersonalPathButton();
+ void handleApply();
+
+ private:
+ void setEnabled(bool state);
+ void setFromSettings();
+ void showFiles(const QStringList& files);
+ SettingsProvider* settings_;
+ Ui::QtSpellCheckerWindow ui_;
+ };
+}
diff --git a/Swift/QtUI/QtSpellCheckerWindow.ui b/Swift/QtUI/QtSpellCheckerWindow.ui
new file mode 100644
index 0000000..b98bb6d
--- /dev/null
+++ b/Swift/QtUI/QtSpellCheckerWindow.ui
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>QtSpellCheckerWindow</class>
+ <widget class="QDialog" name="QtSpellCheckerWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>353</width>
+ <height>207</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="4" column="3" colspan="2">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPushButton" name="cancel">
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="apply">
+ <property name="text">
+ <string>Apply</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="0" colspan="3">
+ <widget class="QCheckBox" name="spellChecker">
+ <property name="text">
+ <string>Spell Checker Enabled</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QLabel" name="pathLabel">
+ <property name="text">
+ <string>Dictionary Path:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2" colspan="2">
+ <widget class="QLineEdit" name="pathContent"/>
+ </item>
+ <item row="1" column="4">
+ <widget class="QPushButton" name="pathButton">
+ <property name="text">
+ <string>Change</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="2">
+ <widget class="QLabel" name="currentLanguage">
+ <property name="text">
+ <string>Current Language:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QLabel" name="currentLanguageValue">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" colspan="4">
+ <widget class="QListWidget" name="languageView"/>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="language">
+ <property name="text">
+ <string>Language:</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Swift/QtUI/QtTextEdit.cpp b/Swift/QtUI/QtTextEdit.cpp
index 0497d01..d1a75dd 100644
--- a/Swift/QtUI/QtTextEdit.cpp
+++ b/Swift/QtUI/QtTextEdit.cpp
@@ -4,18 +4,42 @@
* See Documentation/Licenses/GPLv3.txt for more information.
*/
+#include <boost/tuple/tuple.hpp>
+#include <boost/algorithm/string.hpp>
+#include <boost/bind.hpp>
+
+#include <Swiften/Base/foreach.h>
+
+#include <SwifTools/SpellCheckerFactory.h>
+#include <SwifTools/SpellChecker.h>
+
#include <Swift/QtUI/QtTextEdit.h>
+#include <Swift/QtUI/QtSwiftUtil.h>
+#include <Swift/QtUI/QtSpellCheckerWindow.h>
+#include <Swift/Controllers/SettingConstants.h>
+#include <QApplication>
#include <QFontMetrics>
#include <QKeyEvent>
+#include <QDebug>
+#include <QMenu>
namespace Swift {
-QtTextEdit::QtTextEdit(QWidget* parent) : QTextEdit(parent){
+QtTextEdit::QtTextEdit(SettingsProvider* settings, QWidget* parent) : QTextEdit(parent) {
connect(this, SIGNAL(textChanged()), this, SLOT(handleTextChanged()));
+ checker_ = NULL;
+ settings_ = settings;
+#ifdef HAVE_SPELLCHECKER
+ setUpSpellChecker();
+#endif
handleTextChanged();
}
+QtTextEdit::~QtTextEdit() {
+ delete checker_;
+}
+
void QtTextEdit::keyPressEvent(QKeyEvent* event) {
int key = event->key();
Qt::KeyboardModifiers modifiers = event->modifiers();
@@ -35,13 +59,41 @@ void QtTextEdit::keyPressEvent(QKeyEvent* event) {
emit unhandledKeyPressEvent(event);
}
else if ((key == Qt::Key_Up)
- || (key == Qt::Key_Down)
- ){
+ || (key == Qt::Key_Down)) {
emit unhandledKeyPressEvent(event);
QTextEdit::keyPressEvent(event);
}
else {
QTextEdit::keyPressEvent(event);
+#ifdef HAVE_SPELLCHECKER
+ if (settings_->getSetting(SettingConstants::SPELL_CHECKER)) {
+ underlineMisspells();
+ }
+#endif
+ }
+}
+
+void QtTextEdit::underlineMisspells() {
+ QTextCursor cursor = textCursor();
+ misspelledPositions_.clear();
+ QTextCharFormat normalFormat;
+ cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor, 1);
+ cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor, 1);
+ cursor.setCharFormat(normalFormat);
+ if (checker_ == NULL) {
+ return;
+ }
+ QTextCharFormat spellingErrorFormat;
+ spellingErrorFormat.setUnderlineColor(QColor(Qt::red));
+ spellingErrorFormat.setUnderlineStyle(QTextCharFormat::SpellCheckUnderline);
+ std::string fragment = Q2PSTRING(cursor.selectedText());
+ checker_->checkFragment(fragment, misspelledPositions_);
+ foreach (PositionPair position, misspelledPositions_) {
+ cursor.setPosition(boost::get<0>(position), QTextCursor::MoveAnchor);
+ cursor.setPosition(boost::get<1>(position), QTextCursor::KeepAnchor);
+ cursor.setCharFormat(spellingErrorFormat);
+ cursor.clearSelection();
+ cursor.setCharFormat(normalFormat);
}
}
@@ -53,6 +105,24 @@ void QtTextEdit::handleTextChanged() {
}
}
+void QtTextEdit::replaceMisspelledWord(const QString& word, int cursorPosition) {
+ QTextCursor cursor = textCursor();
+ PositionPair wordPosition = getWordFromCursor(cursorPosition);
+ cursor.setPosition(boost::get<0>(wordPosition), QTextCursor::MoveAnchor);
+ cursor.setPosition(boost::get<1>(wordPosition), QTextCursor::KeepAnchor);
+ QTextCharFormat normalFormat;
+ cursor.insertText(word, normalFormat);
+}
+
+PositionPair QtTextEdit::getWordFromCursor(int cursorPosition) {
+ for (PositionPairList::iterator it = misspelledPositions_.begin(); it != misspelledPositions_.end(); ++it) {
+ if (cursorPosition >= boost::get<0>(*it) && cursorPosition <= boost::get<1>(*it)) {
+ return *it;
+ }
+ }
+ return boost::make_tuple(-1,-1);
+}
+
QSize QtTextEdit::sizeHint() const {
QFontMetrics inputMetrics(currentFont());
QRect horizontalBounds = contentsRect().adjusted(0,0,0,9999);
@@ -66,7 +136,100 @@ QSize QtTextEdit::sizeHint() const {
//return QSize(QTextEdit::sizeHint().width(), lineHeight * numberOfLines);
}
+void QtTextEdit::contextMenuEvent(QContextMenuEvent* event) {
+ QMenu* menu = createStandardContextMenu();
+ QTextCursor cursor = cursorForPosition(event->pos());
+#ifdef HAVE_SPELLCHECKER
+ QAction* insertPoint = menu->actions().first();
+ QAction* settingsAction = new QAction(QApplication::translate("QtTextEdit", "Spell Checker Options", 0, QApplication::UnicodeUTF8), menu);
+ menu->insertAction(insertPoint, settingsAction);
+ menu->insertAction(insertPoint, menu->addSeparator());
+ addSuggestions(menu, event);
+ QAction* result = menu->exec(event->globalPos());
+ if (result == settingsAction) {
+ spellCheckerSettingsWindow();
+ }
+ for (std::vector<QAction*>::iterator it = replaceWordActions_.begin(); it != replaceWordActions_.end(); ++it) {
+ if (*it == result) {
+ replaceMisspelledWord((*it)->text(), cursor.position());
+ }
+ }
+#else
+ menu->exec(event->globalPos());
+#endif
+ delete menu;
}
+void QtTextEdit::addSuggestions(QMenu* menu, QContextMenuEvent* event)
+{
+ replaceWordActions_.clear();
+ QAction* insertPoint = menu->actions().first();
+ QTextCursor cursor = cursorForPosition(event->pos());
+ PositionPair wordPosition = getWordFromCursor(cursor.position());
+ if (boost::get<0>(wordPosition) < 0) {
+ // The click was executed outside a spellable word so no
+ // suggestions are necessary
+ return;
+ }
+ cursor.setPosition(boost::get<0>(wordPosition), QTextCursor::MoveAnchor);
+ cursor.setPosition(boost::get<1>(wordPosition), QTextCursor::KeepAnchor);
+ std::vector<std::string> wordList;
+ checker_->getSuggestions(Q2PSTRING(cursor.selectedText()), wordList);
+ if (wordList.size() == 0) {
+ QAction* noSuggestions = new QAction(QApplication::translate("QtTextEdit", "No Suggestions", 0, QApplication::UnicodeUTF8), menu);
+ noSuggestions->setDisabled(true);
+ menu->insertAction(insertPoint, noSuggestions);
+ }
+ else {
+ for (std::vector<std::string>::iterator it = wordList.begin(); it != wordList.end(); ++it) {
+ QAction* wordAction = new QAction(it->c_str(), menu);
+ menu->insertAction(insertPoint, wordAction);
+ replaceWordActions_.push_back(wordAction);
+ }
+ }
+ menu->insertAction(insertPoint, menu->addSeparator());
+}
+#ifdef HAVE_SPELLCHECKER
+void QtTextEdit::setUpSpellChecker()
+{
+ SpellCheckerFactory* checkerFactory = new SpellCheckerFactory();
+ delete checker_;
+ if (settings_->getSetting(SettingConstants::SPELL_CHECKER)) {
+ std::string dictPath = settings_->getSetting(SettingConstants::DICT_PATH);
+ std::string dictFile = settings_->getSetting(SettingConstants::DICT_FILE);
+ checker_ = checkerFactory->createSpellChecker(dictPath + dictFile);
+ delete checkerFactory;
+ }
+ else {
+ checker_ = NULL;
+ }
+}
+#endif
+
+void QtTextEdit::spellCheckerSettingsWindow() {
+ if (!spellCheckerWindow_) {
+ spellCheckerWindow_ = new QtSpellCheckerWindow(settings_);
+ settings_->onSettingChanged.connect(boost::bind(&QtTextEdit::handleSettingChanged, this, _1));
+ spellCheckerWindow_->show();
+ }
+ else {
+ spellCheckerWindow_->show();
+ spellCheckerWindow_->raise();
+ spellCheckerWindow_->activateWindow();
+ }
+}
+
+void QtTextEdit::handleSettingChanged(const std::string& settings) {
+ if (settings == SettingConstants::SPELL_CHECKER.getKey()
+ || settings == SettingConstants::DICT_PATH.getKey()
+ || settings == SettingConstants::DICT_FILE.getKey()) {
+#ifdef HAVE_SPELLCHECKER
+ setUpSpellChecker();
+ underlineMisspells();
+#endif
+ }
+}
+
+}
diff --git a/Swift/QtUI/QtTextEdit.h b/Swift/QtUI/QtTextEdit.h
index 075728b..a8df4d3 100644
--- a/Swift/QtUI/QtTextEdit.h
+++ b/Swift/QtUI/QtTextEdit.h
@@ -5,20 +5,46 @@
*/
#pragma once
+
+#include <SwifTools/SpellParser.h>
+
+#include <Swift/Controllers/Settings/SettingsProvider.h>
+#include <Swift/Controllers/SettingConstants.h>
+
#include <QTextEdit>
+#include <QPointer>
namespace Swift {
+ class SpellChecker;
+ class QtSpellCheckerWindow;
class QtTextEdit : public QTextEdit {
Q_OBJECT
public:
- QtTextEdit(QWidget* parent = 0);
+ QtTextEdit(SettingsProvider* settings, QWidget* parent = 0);
+ virtual ~QtTextEdit();
virtual QSize sizeHint() const;
signals:
+ void wordCorrected(QString& word);
void returnPressed();
void unhandledKeyPressEvent(QKeyEvent* event);
+ public slots:
+ void handleSettingChanged(const std::string& settings);
protected:
virtual void keyPressEvent(QKeyEvent* event);
+ virtual void contextMenuEvent(QContextMenuEvent* event);
private slots:
void handleTextChanged();
+ private:
+ SpellChecker *checker_;
+ std::vector<QAction*> replaceWordActions_;
+ PositionPairList misspelledPositions_;
+ SettingsProvider *settings_;
+ QPointer<QtSpellCheckerWindow> spellCheckerWindow_;
+ void addSuggestions(QMenu* menu, QContextMenuEvent* event);
+ void replaceMisspelledWord(const QString& word, int cursorPosition);
+ void setUpSpellChecker();
+ void underlineMisspells();
+ void spellCheckerSettingsWindow();
+ PositionPair getWordFromCursor(int cursorPosition);
};
}
diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript
index 13d36fa..bfa35a5 100644
--- a/Swift/QtUI/SConscript
+++ b/Swift/QtUI/SConscript
@@ -45,6 +45,8 @@ if myenv["swift_mobile"] :
if myenv.get("HAVE_SNARL", False) :
myenv.UseFlags(myenv["SNARL_FLAGS"])
myenv.Append(CPPDEFINES = ["HAVE_SNARL"])
+if myenv.get("HAVE_HUNSPELL", True):
+ myenv.Append(CPPDEFINES = ["HAVE_HUNSPELL"])
if env["PLATFORM"] == "win32" :
myenv.Append(LIBS = ["cryptui"])
myenv.UseFlags(myenv["PLATFORM_FLAGS"])
@@ -83,6 +85,7 @@ myenv.WriteVal("DefaultTheme.qrc", myenv.Value(generateDefaultTheme(myenv.Dir("#
sources = [
"main.cpp",
"QtAboutWidget.cpp",
+ "QtSpellCheckerWindow.cpp",
"QtAvatarWidget.cpp",
"QtUIFactory.cpp",
"QtChatWindowFactory.cpp",
@@ -270,6 +273,7 @@ myenv.Uic4("QtHistoryWindow.ui")
myenv.Uic4("QtConnectionSettings.ui")
myenv.Uic4("QtHighlightRuleWidget.ui")
myenv.Uic4("QtHighlightEditorWidget.ui")
+myenv.Uic4("QtSpellCheckerWindow.ui")
myenv.Qrc("DefaultTheme.qrc")
myenv.Qrc("Swift.qrc")