diff options
Diffstat (limited to 'quacker')
-rw-r--r-- | quacker/Info.plist | 2 | ||||
-rw-r--r-- | quacker/boardsetupdialog.cpp | 23 | ||||
-rw-r--r-- | quacker/boardsetupdialog.h | 2 | ||||
-rw-r--r-- | quacker/graphicalreporter.cpp | 1 | ||||
-rw-r--r-- | quacker/lexicondialog.cpp | 306 | ||||
-rw-r--r-- | quacker/lexicondialog.h | 86 | ||||
-rw-r--r-- | quacker/lister.cpp | 3 | ||||
-rw-r--r-- | quacker/quacker.cpp | 36 | ||||
-rw-r--r-- | quacker/quacker.plist | 2 | ||||
-rw-r--r-- | quacker/quacker.pro | 17 | ||||
-rw-r--r-- | quacker/settings.cpp | 380 | ||||
-rw-r--r-- | quacker/settings.h | 32 |
12 files changed, 739 insertions, 151 deletions
diff --git a/quacker/Info.plist b/quacker/Info.plist index 015f161..854c8a9 100644 --- a/quacker/Info.plist +++ b/quacker/Info.plist @@ -26,7 +26,7 @@ <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleShortVersionString</key> - <string>0.98</string> + <string>1.0</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key> diff --git a/quacker/boardsetupdialog.cpp b/quacker/boardsetupdialog.cpp index 7198b17..2bfd5ff 100644 --- a/quacker/boardsetupdialog.cpp +++ b/quacker/boardsetupdialog.cpp @@ -33,7 +33,7 @@ BoardSetupDialog::BoardSetupDialog(QWidget *parent) : QDialog(parent) { - resize(600,450); + resize(700,550); setSizeGripEnabled(true); // construct the board @@ -58,6 +58,7 @@ BoardSetupDialog::BoardSetupDialog(QWidget *parent) : QDialog(parent) m_saveChanges = new QPushButton(tr("&Save Changes")); m_cancel = new QPushButton(tr("&Cancel")); m_undoAll = new QPushButton(tr("&Undo All Changes")); + m_deleteBoard = new QPushButton(tr("&Delete Board")); QVBoxLayout * superLayout = new QVBoxLayout; Geometry::setupFramedLayout(superLayout); @@ -96,6 +97,8 @@ BoardSetupDialog::BoardSetupDialog(QWidget *parent) : QDialog(parent) leftSideLayout->addWidget(dimensionGroup); leftSideLayout->addWidget(symmetryGroup); leftSideLayout->addWidget(m_undoAll); + if (!m_originalName.isEmpty()) + leftSideLayout->addWidget(m_deleteBoard); leftSideLayout->addStretch(); mainLayout->addLayout(leftSideLayout); @@ -118,6 +121,7 @@ BoardSetupDialog::BoardSetupDialog(QWidget *parent) : QDialog(parent) connect(m_saveChanges, SIGNAL(clicked()), this, SLOT(accept())); connect(m_cancel, SIGNAL(clicked()), this, SLOT(reject())); connect(m_undoAll, SIGNAL(clicked()), this, SLOT(undoAllChanges())); + connect(m_deleteBoard, SIGNAL(clicked()), this, SLOT(deleteBoard())); connect(m_horizontalSymmetry, SIGNAL(stateChanged(int)), this, SLOT(symmetryChanged())); connect(m_verticalSymmetry, SIGNAL(stateChanged(int)), this, SLOT(symmetryChanged())); connect(m_diagonalSymmetry, SIGNAL(stateChanged(int)), this, SLOT(symmetryChanged())); @@ -239,3 +243,20 @@ void BoardSetupDialog::undoAllChanges() QUACKLE_DATAMANAGER->setBoardParameters(Quackle::BoardParameters::Deserialize(boardStream)); parametersChanged(QString()); } + +void BoardSetupDialog::deleteBoard() +{ + QString message = "Do you really want to delete the game board \""; + message += m_originalName; + message += "\"?"; + if (QMessageBox::warning(NULL, QString("Confirm Deletion"), message, + QMessageBox::Yes | QMessageBox::Default, + QMessageBox::No | QMessageBox::Escape) == QMessageBox::Yes) + { + CustomQSettings settings; + settings.beginGroup("quackle/boardparameters"); + settings.remove(m_originalName); + QDialog::reject(); + } +} + diff --git a/quacker/boardsetupdialog.h b/quacker/boardsetupdialog.h index e5432cc..0176d1a 100644 --- a/quacker/boardsetupdialog.h +++ b/quacker/boardsetupdialog.h @@ -48,6 +48,7 @@ protected slots: void parametersChanged(const QString &unused); void symmetryChanged(); void undoAllChanges(); + void deleteBoard(); private: QCheckBox *m_horizontalSymmetry; @@ -62,6 +63,7 @@ private: QPushButton *m_saveChanges; QPushButton *m_cancel; QPushButton *m_undoAll; + QPushButton *m_deleteBoard; Quackle::Game m_game; BoardSetupFrame * m_boardFrame; diff --git a/quacker/graphicalreporter.cpp b/quacker/graphicalreporter.cpp index f7c9ce7..2fb0842 100644 --- a/quacker/graphicalreporter.cpp +++ b/quacker/graphicalreporter.cpp @@ -227,5 +227,6 @@ void GraphicalReporter::openIndex() m_indexStream.setDevice(&m_indexFile); } + m_indexStream.setCodec(QTextCodec::codecForName("UTF-8")); } diff --git a/quacker/lexicondialog.cpp b/quacker/lexicondialog.cpp new file mode 100644 index 0000000..91eb676 --- /dev/null +++ b/quacker/lexicondialog.cpp @@ -0,0 +1,306 @@ +/* + * Quackle -- Crossword game artificial intelligence and analysis tool + * Copyright (C) 2005-2014 Jason Katz-Brown and John O'Laughlin. + * + * 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 3 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, see <http://www.gnu.org/licenses/>. + */ + +#include <sstream> +#include <QtGui> +#include <datamanager.h> +#include <quackleio/util.h> + +#include "lexicondialog.h" +#include "customqsettings.h" +#include "settings.h" +#include "geometry.h" +#include "quackleio/dawgfactory.h" + +class FileNameValidator : public QValidator +{ +public: + virtual State validate(QString &input, int &pos) const + { + for (QString::ConstIterator i = input.begin(); i != input.end(); ++i) + if (*i == '/' || *i == '?' || *i == '\\' || *i == '*') + return Invalid; + return Acceptable; + } +}; + +LexiconDialog::LexiconDialog(QWidget *parent, const QString &originalName) : QDialog(parent), + m_deleted(false), m_wordFactory(NULL) +{ + m_originalName = originalName; + + resize(450,350); + + // construct the UI elements + m_lexiconName = new QLineEdit(); + m_alphabetCombo = new QComboBox(); + m_fileNameValidator = new FileNameValidator(); + + m_addWordsFromFile = new QPushButton(tr("Add words from &file...")); + m_clearAllWords = new QPushButton(tr("Clear &words and start again")); + + + m_lexiconInformation = new QLabel(""); + m_lexiconInformation->setWordWrap(true); + m_lexiconInformation->setTextInteractionFlags(Qt::TextBrowserInteraction); + + m_saveChanges = new QPushButton(tr("&Save Changes")); + m_cancel = new QPushButton(tr("&Cancel")); + m_deleteLexicon = new QPushButton(tr("&Delete Lexicon")); + + QLabel * lexiconNameLabel = new QLabel(tr("&Lexicon name:")); + QLabel * alphabetLabel = new QLabel(tr("&Alphabet:")); + lexiconNameLabel->setBuddy(m_lexiconName); + alphabetLabel->setBuddy(m_alphabetCombo); + + QVBoxLayout * layout = new QVBoxLayout; + Geometry::setupFramedLayout(layout); + QHBoxLayout * lexiconRow = new QHBoxLayout; + Geometry::setupInnerLayout(lexiconRow); + QHBoxLayout * addRemoveWordsRow = new QHBoxLayout; + Geometry::setupInnerLayout(addRemoveWordsRow); + QHBoxLayout * buttonRow = new QHBoxLayout; + Geometry::setupInnerLayout(buttonRow); + QGroupBox * lexiconInformationGroup = new QGroupBox(tr("Lexicon information")); + QVBoxLayout * lexiconInformationLayout = new QVBoxLayout(lexiconInformationGroup); + + // build the layout + lexiconRow->addWidget(lexiconNameLabel); + lexiconRow->addWidget(m_lexiconName); + lexiconRow->addStretch(); + lexiconRow->addWidget(alphabetLabel); + lexiconRow->addWidget(m_alphabetCombo); + + addRemoveWordsRow->addWidget(m_addWordsFromFile); + addRemoveWordsRow->addWidget(m_clearAllWords); + + lexiconInformationLayout->addWidget(m_lexiconInformation); + + buttonRow->addWidget(m_deleteLexicon); + buttonRow->addStretch(); + buttonRow->addWidget(m_cancel); + buttonRow->addWidget(m_saveChanges); + + layout->addLayout(lexiconRow); + layout->addLayout(addRemoveWordsRow); + layout->addWidget(lexiconInformationGroup); + layout->addStretch(); + layout->addLayout(buttonRow); + + setLayout(layout); + m_saveChanges->setDefault(true); + + // hook up signals and slots + connect(m_lexiconName, SIGNAL(textEdited(const QString &)), this, SLOT(parametersChanged(const QString &))); + connect(m_addWordsFromFile, SIGNAL(clicked()), this, SLOT(addWordsFromFile())); + connect(m_clearAllWords, SIGNAL(clicked()), this, SLOT(loadOriginalDictionary())); + connect(m_saveChanges, SIGNAL(clicked()), this, SLOT(accept())); + connect(m_cancel, SIGNAL(clicked()), this, SLOT(reject())); + connect(m_deleteLexicon, SIGNAL(clicked()), this, SLOT(deleteLexicon())); + connect(m_alphabetCombo, SIGNAL(activated(const QString &)), this, SLOT(alphabetChanged(const QString &))); + + setWindowTitle(tr("Configure Lexicon - Quackle")); + + Settings::populateComboFromFilenames(m_alphabetCombo, "alphabets", ".quackle_alphabet", ""); + m_alphabetCombo->setCurrentIndex(m_alphabetCombo->findText(QuackleIO::Util::stdStringToQString(QUACKLE_ALPHABET_PARAMETERS->alphabetName()))); + alphabetChanged(m_alphabetCombo->currentText()); + + m_lexiconName->setValidator(m_fileNameValidator); + m_lexiconName->setText(m_originalName); + + loadOriginalDictionary(); +} + +LexiconDialog::~LexiconDialog() +{ + delete m_fileNameValidator; + delete m_wordFactory; +} + +void LexiconDialog::deleteLexicon() +{ + string lexiconNameStr = m_originalName.toStdString(); + string filename = QUACKLE_DATAMANAGER->makeDataFilename("lexica", lexiconNameStr + ".dawg", true); + QFile(QString::fromStdString(filename)).remove(); + m_deleted = true; + QDialog::accept(); +} + +void LexiconDialog::addWordsFromFile() +{ + QFileDialog browser(this, tr("Choose a file containing words to be added to the lexicon...")); + QStringList filters; + filters << "Dictionary files (*.txt *.dawg *.raw)" + << "All files (*.*)"; + browser.setNameFilters(filters); + browser.setFileMode(QFileDialog::ExistingFiles); + browser.exec(); + + QStringList files = browser.selectedFiles(); + for (QList<QString>::const_iterator it = files.begin(); it != files.end(); it++) + { + if (it->endsWith(".dawg", Qt::CaseInsensitive)) + addWordsFromDawgFile(*it); + else + addWordsFromTextFile(*it); + } + updateLexiconInformation(); +} + +void LexiconDialog::alphabetChanged(const QString &alphabet) +{ + delete m_wordFactory; + m_wordFactory = NULL; + updateLexiconInformation(); + m_alphabetFileName = QString::fromStdString(AlphabetParameters::findAlphabetFile(QuackleIO::Util::qstringToStdString(alphabet))); +} + +void LexiconDialog::addWordsFromDawgFile(const QString &dawgfile) +{ + if (!m_wordFactory) + m_wordFactory = new DawgFactory(m_alphabetFileName); + LexiconParameters lexParams; + lexParams.loadDawg(QuackleIO::Util::qstringToStdString(dawgfile)); + if (!lexParams.hasDawg()) + return; + + Quackle::LetterString word; + + addWordsFromDawgRecursive(lexParams, word, 1); +} + +void LexiconDialog::addWordsFromDawgRecursive(const LexiconParameters &lexParams, Quackle::LetterString &word, int index) +{ + unsigned int p; + Quackle::Letter letter; + bool t; + bool lastchild; + bool british; + int playability; + + do + { + lexParams.dawgAt(index, p, letter, t, lastchild, british, playability); + word.push_back(letter); + if (t) + m_wordFactory->pushWord(word, !british, playability); + if (p) + addWordsFromDawgRecursive(lexParams, word, p); + index++; + word.pop_back(); + } while (!lastchild); +} + +void LexiconDialog::addWordsFromTextFile(const QString &textFile) +{ + if (!m_wordFactory) + m_wordFactory = new DawgFactory(m_alphabetFileName); + + QFile file(textFile); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + return; + + QTextStream stream(&file); + stream.setCodec("UTF-8"); + QString word; + while (!stream.atEnd()) + { + stream >> word; + word = word.trimmed().toUpper(); + if (word.isEmpty()) + continue; + QChar firstChar = word[0]; + if (firstChar < 'A') + continue; // allows the usage of most punctuation characters as comments + int playability = 0; + for (int i = word.size() - 1; i > 0; i--) + { + if (word[i].isDigit()) + playability = playability * 10 + word[i].digitValue(); + } + m_wordFactory->pushWord(QuackleIO::Util::qstringToString(word), true, playability); + } +} + +void LexiconDialog::loadOriginalDictionary() +{ + delete m_wordFactory; + m_wordFactory = NULL; + string dawgFileName = m_originalName.toStdString() + ".dawg"; + QString dawgFullFileName; + if (!m_originalName.isEmpty()) + dawgFullFileName = QString::fromStdString(Quackle::LexiconParameters::findDictionaryFile(dawgFileName)); + + if (!dawgFullFileName.isEmpty()) + { + m_deleteLexicon->setEnabled(Quackle::LexiconParameters::hasUserDictionaryFile(dawgFileName)); + m_lexiconInformation->setText(tr("Loading dictionary...")); + show(); + qApp->processEvents(); + addWordsFromDawgFile(dawgFullFileName); + } + else + m_deleteLexicon->setEnabled(false); + + updateLexiconInformation(true); +} + +void LexiconDialog::accept() +{ + string lexiconNameStr = m_lexiconName->text().toStdString(); + string filename = QUACKLE_DATAMANAGER->makeDataFilename("lexica", lexiconNameStr + ".dawg", true); + m_lexiconInformation->setText(tr("Compressing and writing dictionary file...\nThis may take a few minutes.")); + qApp->processEvents(); + m_wordFactory->generate(); + m_lexiconInformation->setText(tr("Writing dictionary file...")); + qApp->processEvents(); + m_wordFactory->writeIndex(filename); + m_finalLexiconName = m_lexiconName->text(); + QDialog::accept(); +} + +void LexiconDialog::updateLexiconInformation(bool firstTime) +{ + QByteArray hash = m_wordFactory ? QByteArray(m_wordFactory->hashBytes(), 16).toHex() : ""; + QString text; + QString lengthText; + + int wordCount = m_wordFactory ? m_wordFactory->wordCount() : 0; + if (wordCount == 0) + { + delete m_wordFactory; + m_wordFactory = NULL; + } + if (m_wordFactory) + lengthText = QString::fromStdString(m_wordFactory->letterCountString()); + + if (firstTime) + m_originalHash = hash; + + text.append(tr("Word count: ")); + text.append(QString("%L1").arg(wordCount)); + text.append("\n"); + text.append(lengthText); + text.append(tr("\nLexicon hash: ")); + text.append(hash.left(8)); + + m_lexiconInformation->setText(text); + + m_saveChanges->setEnabled(true/*hash != m_originalHash && !m_lexiconName->text().isEmpty()*/); + m_clearAllWords->setEnabled(hash != m_originalHash); +} diff --git a/quacker/lexicondialog.h b/quacker/lexicondialog.h new file mode 100644 index 0000000..1f1605b --- /dev/null +++ b/quacker/lexicondialog.h @@ -0,0 +1,86 @@ +/* + * Quackle -- Crossword game artificial intelligence and analysis tool + * Copyright (C) 2005-2014 Jason Katz-Brown and John O'Laughlin. + * + * 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 3 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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef QUACKER_LEXICONDIALOG_H +#define QUACKER_LEXICONDIALOG_H + +#include <string> +#include "game.h" +#include "lexiconparameters.h" + +#include <QWidget> +#include <QDialog> + +using namespace std; +using namespace Quackle; + +class QComboBox; +class QLabel; +class QLineEdit; +class QPushButton; +class DawgFactory; +class FileNameValidator; + +class LexiconDialog : public QDialog +{ +Q_OBJECT + +public: + LexiconDialog(QWidget *parent = 0, const QString &originalName = QString()); + ~LexiconDialog(); + virtual void accept(); + + bool itemWasDeleted() { return m_deleted; }; + const QString &lexiconName() { return m_finalLexiconName; }; + + void updateLexiconInformation(bool firstTime = false); + +protected slots: + void parametersChanged(const QString &) { updateLexiconInformation(); }; + void deleteLexicon(); + void addWordsFromFile(); + void alphabetChanged(const QString &); + void loadOriginalDictionary(); + +protected: + void addWordsFromDawgFile(const QString &dawgfile); + void addWordsFromDawgRecursive(const LexiconParameters &lexParams, Quackle::LetterString &word, int index); + void addWordsFromTextFile(const QString &textFile); + +private: + QLineEdit *m_lexiconName; + QComboBox *m_alphabetCombo; + QPushButton *m_addWordsFromFile; + QPushButton *m_clearAllWords; + QLabel *m_lexiconInformation; + FileNameValidator * m_fileNameValidator; + + QPushButton *m_saveChanges; + QPushButton *m_cancel; + QPushButton *m_deleteLexicon; + + QString m_originalName; + QString m_alphabetFileName; + QByteArray m_originalHash; + QString m_finalLexiconName; + bool m_deleted; + + DawgFactory *m_wordFactory; +}; + +#endif diff --git a/quacker/lister.cpp b/quacker/lister.cpp index 278bff1..be3e335 100644 --- a/quacker/lister.cpp +++ b/quacker/lister.cpp @@ -667,7 +667,6 @@ void NumAnagramsFilter::apply() { int twl = 0; int british = 0; - int playability = 0; QString alphagram(QuackleIO::DictFactory::querier()->alphagram((*it).word)); for (Dict::WordList::Iterator word = map[alphagram].begin(); word != map[alphagram].end(); ++word) @@ -676,8 +675,6 @@ void NumAnagramsFilter::apply() british++; else twl++; - - playability += (*word).playability; } if ((twl == numTwlAnagrams) && (british == numOswOnlyAnagrams)) diff --git a/quacker/quacker.cpp b/quacker/quacker.cpp index 098ff84..2f407fa 100644 --- a/quacker/quacker.cpp +++ b/quacker/quacker.cpp @@ -155,13 +155,10 @@ void TopLevel::finishInitialization() void TopLevel::introduceToUser() { CustomQSettings settings; - QString lexiconName = settings.value("quackle/settings/lexicon-name", QString("twl06")).toString(); - if (lexiconName == "csw12") { - statusMessage(tr("The WESPA wordlist (CSW12) is copyright Harper Collins 2011.")); - } else { - statusMessage(tr("Enjoy your quackling. Choose \"New game...\" from the Game menu to begin.")); - } - + QString statusText = QString::fromUtf8(QUACKLE_LEXICON_PARAMETERS->copyrightString().c_str()); + if (statusText.isEmpty()) + statusText = tr("Enjoy your quackling. Choose \"New game...\" from the Game menu to begin."); + statusMessage(statusText); parseCommandLineOptions(); if (!CustomQSettings().contains("quackle/hasBeenRun")) @@ -2120,17 +2117,34 @@ void TopLevel::firstTimeRun() void TopLevel::about() { - QMessageBox::about(this, tr("About Quackle 0.98"), dialogText(tr( -"<p><b>Quackle</b> 0.98 is a crossword game playing, analysis, and study tool. Visit the Quackle homepage at <tt><a href=\"http://quackle.org\">http://quackle.org</a></tt> for more information.</p>" + QString aboutText = tr( +"<p><b>Quackle</b> 1.0 is a crossword game playing, analysis, and study tool. Visit the Quackle homepage at <tt><a href=\"http://quackle.org\">http://quackle.org</a></tt> for more information.</p>" "<p>Quackle was written by Jason Katz-Brown, John O'Laughlin, John Fultz, Matt Liberty, and Anand Buddhdev. We thank the anonymous donor who made this software free.</p>" -"<p>Copyright 2005-2014 by</p>" +"<p>Copyright 2005-2015 by</p>" "<ul>" "<li>Jason Katz-Brown <jasonkatzbrown@gmail.com></li>" "<li>John O'Laughlin <olaughlin@gmail.com></li>" "</ul>" "<p>Quackle is free, open-source software licensed under the terms of the GNU General Public License Version 3. See</p>" "<p><tt><a href=\"http://quackle.org/LICENSE\">http://quackle.org/LICENSE</a></tt></p>" -))); +"<p>Dictionary copyrights</p><ul>" +); + + FILE* file = fopen(QUACKLE_DATAMANAGER->makeDataFilename("lexica", "copyrights.txt", false).c_str(), "r"); + if (file) + { + QTextStream strm(file); + while (!strm.atEnd()) + { + QString line = strm.readLine(); + int pos = line.indexOf(':'); + if (pos != -1 && pos + 1 < line.size()) + aboutText += "<li>" + line.mid(pos + 1) + "</li>"; + } + fclose(file); + aboutText += "</ul>"; + } + QMessageBox::about(this, tr("About Quackle 1.0"), dialogText(aboutText)); } void TopLevel::hints() diff --git a/quacker/quacker.plist b/quacker/quacker.plist index bf6b31e..eef0ac9 100644 --- a/quacker/quacker.plist +++ b/quacker/quacker.plist @@ -21,6 +21,6 @@ <key>NSPrincipalClass</key> <string>NSApplication</string> <key>NSHumanReadableCopyright</key> - <string>Copyright © 2005-2013 by Jason Katz-Brown & John O'Laughlin</string> + <string>Copyright © 2005-2015 by Jason Katz-Brown & John O'Laughlin</string> </dict> </plist> diff --git a/quacker/quacker.pro b/quacker/quacker.pro index 9906e45..6e3f2e0 100644 --- a/quacker/quacker.pro +++ b/quacker/quacker.pro @@ -1,5 +1,5 @@ TEMPLATE = app -VERSION = 0.99 +VERSION = 1.0 TARGET = Quackle DEPENDPATH += .. ../quackleio INCLUDEPATH += . .. @@ -10,19 +10,18 @@ MOC_DIR = moc #CONFIG += debug CONFIG += release +#Um, why is this necessary? I don't know. But if this isn't here, +#qmake messes up resulting Visual Studio project files. +CONFIG -= debug + debug { OBJECTS_DIR = obj/debug + QMAKE_LIBDIR += ../lib/debug ../quackleio/lib/debug } release { OBJECTS_DIR = obj/release -} - -debug { - QMAKE_LIBDIR += ../lib/debug ../quackleio/lib/debug -} -release { - QMAKE_LIBDIR += ../lib/release ../quackleio/lib/release + QMAKE_LIBDIR += ../lib/release ../quackleio/lib/release } win32:!win32-g++ { @@ -32,6 +31,8 @@ win32:!win32-g++ { } macx:LIBS += -framework CoreFoundation +QMAKE_CXXFLAGS += -std=c++11 + # Input HEADERS += *.h SOURCES += *.cpp diff --git a/quacker/settings.cpp b/quacker/settings.cpp index 301608e..e22a29e 100644 --- a/quacker/settings.cpp +++ b/quacker/settings.cpp @@ -45,6 +45,7 @@ #include "boardsetupdialog.h" #include "customqsettings.h" #include "graphicalboard.h" +#include "lexicondialog.h" Settings *Settings::m_self = 0; Settings *Settings::self() @@ -80,17 +81,20 @@ Settings::Settings(QWidget *parent) #endif if (QFile::exists("data")) - m_dataDir = "data"; + m_appDataDir = "data"; else if (QFile::exists("../data")) - m_dataDir = "../data"; + m_appDataDir = "../data"; else if (QFile::exists("Quackle.app/Contents/data")) - m_dataDir = "Quackle.app/Contents/data"; + m_appDataDir = "Quackle.app/Contents/data"; else { if (!directory.cd("data") || !directory.cd("../data")) QMessageBox::critical(0, tr("Error Initializing Data Files - Quacker"), tr("<p>Could not open data directory. Quackle will be useless. Try running the quacker executable with quackle/quacker/ as the current directory.</p>")); - m_dataDir = directory.absolutePath(); + m_appDataDir = directory.absolutePath(); } + m_userDataDir = QDesktopServices::storageLocation(QDesktopServices::DataLocation); + QDir qdir(m_userDataDir); + qdir.mkpath("lexica"); } void Settings::createGUI() @@ -98,93 +102,88 @@ void Settings::createGUI() if (m_lexiconNameCombo != 0) return; - QVBoxLayout *vlayout = new QVBoxLayout(this); + QGridLayout *layout = new QGridLayout(this); m_lexiconNameCombo = new QComboBox; connect(m_lexiconNameCombo, SIGNAL(activated(const QString &)), this, SLOT(lexiconChanged(const QString &))); - QStringList items; - populateListFromFilenames(items, m_dataDir + "/lexica"); - m_lexiconNameCombo->addItems(items); + populateComboFromFilenames(m_lexiconNameCombo, "lexica", ".dawg", "lexicon"); - QLabel *cswText = new QLabel(tr("The WESPA wordlist (CSW12) is copyright Harper Collins 2011.")); - - QHBoxLayout *lexiconLayout = new QHBoxLayout; QLabel *lexiconNameLabel = new QLabel(tr("&Lexicon:")); lexiconNameLabel->setBuddy(m_lexiconNameCombo); - - lexiconLayout->addWidget(lexiconNameLabel); - lexiconLayout->addWidget(m_lexiconNameCombo); + m_editLexicon = new QPushButton(tr("Edit...")); + m_editLexicon->setMaximumWidth(60); + connect(m_editLexicon, SIGNAL(clicked()), this, SLOT(editLexicon())); m_alphabetNameCombo = new QComboBox; connect(m_alphabetNameCombo, SIGNAL(activated(const QString &)), this, SLOT(alphabetChanged(const QString &))); - QStringList alphabetItems; - populateListFromFilenames(alphabetItems, m_dataDir + "/alphabets"); - m_alphabetNameCombo->addItems(alphabetItems); + populateComboFromFilenames(m_alphabetNameCombo, "alphabets", ".quackle_alphabet", ""); - QHBoxLayout *alphabetLayout = new QHBoxLayout; QLabel *alphabetNameLabel = new QLabel(tr("&Alphabet:")); alphabetNameLabel->setBuddy(m_alphabetNameCombo); - - alphabetLayout->addWidget(alphabetNameLabel); - alphabetLayout->addWidget(m_alphabetNameCombo); + m_editAlphabet = new QPushButton(tr("Edit...")); + m_editAlphabet->setMaximumWidth(60); + connect(m_editAlphabet, SIGNAL(clicked()), this, SLOT(editAlphabet())); m_themeNameCombo = new QComboBox; connect(m_themeNameCombo, SIGNAL(activated(const QString &)), this, SLOT(themeChanged(const QString &))); - QStringList themeItems; - populateListFromFilenames(themeItems, m_dataDir + "/themes"); - m_themeNameCombo->addItems(themeItems); + populateComboFromFilenames(m_themeNameCombo, "themes", ".ini", ""); - QHBoxLayout *themeLayout = new QHBoxLayout; QLabel *themeNameLabel = new QLabel(tr("&Theme:")); themeNameLabel->setBuddy(m_themeNameCombo); + m_editTheme = new QPushButton(tr("Edit...")); + m_editTheme->setMaximumWidth(60); + connect(m_editTheme, SIGNAL(clicked()), this, SLOT(editTheme())); - themeLayout->addWidget(themeNameLabel); - themeLayout->addWidget(m_themeNameCombo); - - m_boardNameCombo = new QComboBox(); + m_boardNameCombo = new QComboBox; connect(m_boardNameCombo, SIGNAL(activated(const QString &)), this, SLOT(boardChanged(const QString &))); - m_addBoard = new QPushButton(tr("Add Board")); - connect(m_addBoard, SIGNAL(clicked()), this, SLOT(addBoard())); + populateComboFromFilenames(m_boardNameCombo, "boards", "", "board"); - m_editBoard = new QPushButton(tr("&Edit Board")); + QLabel *boardNameLabel = new QLabel(tr("&Board:")); + boardNameLabel->setBuddy(m_boardNameCombo); + m_editBoard = new QPushButton(tr("Edit...")); + m_editBoard->setMaximumWidth(60); connect(m_editBoard, SIGNAL(clicked()), this, SLOT(editBoard())); - m_deleteBoard = new QPushButton(tr("&Delete Board")); - connect(m_deleteBoard, SIGNAL(clicked()), this, SLOT(deleteBoard())); + m_copyrightLabel = new QLabel(); - loadBoardNameCombo(); + layout->addWidget(lexiconNameLabel, 0, 0, Qt::AlignRight); + layout->addWidget(m_lexiconNameCombo, 0, 1); + layout->addWidget(m_editLexicon, 0, 2); + layout->addWidget(alphabetNameLabel, 1, 0, Qt::AlignRight); + layout->addWidget(m_alphabetNameCombo, 1, 1); + // layout->addWidget(m_editAlphabet, 1, 2); + layout->addWidget(themeNameLabel, 2, 0, Qt::AlignRight); + layout->addWidget(m_themeNameCombo, 2, 1); + // layout->addWidget(m_editTheme, 2, 2); + layout->addWidget(boardNameLabel, 3, 0, Qt::AlignRight); + layout->addWidget(m_boardNameCombo, 3, 1); + layout->addWidget(m_editBoard, 3, 2); + layout->addWidget(m_copyrightLabel, 4, 0, 1, -1, Qt::AlignTop); - QGroupBox *boardGroup = new QGroupBox("Game Board Definitions"); - QGridLayout *boardLayout = new QGridLayout(boardGroup); - QLabel *boardNameLabel = new QLabel(tr("&Board:")); - boardNameLabel->setBuddy(m_boardNameCombo); + layout->setColumnMinimumWidth(3, 0); + layout->setColumnStretch(3, 1); + layout->setRowMinimumHeight(4, 0); + layout->setRowStretch(4, 1); - boardLayout->addWidget(boardNameLabel, 0, 0); - boardLayout->addWidget(m_boardNameCombo, 0, 1, 1, -1); - boardLayout->addWidget(m_addBoard, 1, 0); - boardLayout->addWidget(m_editBoard, 1, 1); - boardLayout->addWidget(m_deleteBoard, 1, 2); - - vlayout->addWidget(cswText); - vlayout->addLayout(lexiconLayout); - vlayout->addLayout(alphabetLayout); - vlayout->addLayout(themeLayout); - vlayout->addWidget(boardGroup); - vlayout->addStretch(); load(); } void Settings::load() { - m_lexiconNameCombo->setCurrentIndex(m_lexiconNameCombo->findText(QuackleIO::Util::stdStringToQString(QUACKLE_LEXICON_PARAMETERS->lexiconName()))); - m_alphabetNameCombo->setCurrentIndex(m_alphabetNameCombo->findText(QuackleIO::Util::stdStringToQString(QUACKLE_ALPHABET_PARAMETERS->alphabetName()))); + m_lexiconNameCombo->setCurrentIndex(m_lexiconNameCombo->findText(QString::fromUtf8(QUACKLE_LEXICON_PARAMETERS->lexiconName().c_str()))); + if (m_lexiconNameCombo->currentIndex() == -1) + m_lexiconNameCombo->setCurrentIndex(m_lexiconNameCombo->findText(QString::fromUtf8(QUACKLE_LEXICON_PARAMETERS->lexiconName().c_str()) + "*")); + m_lastGoodLexiconValue = m_lexiconNameCombo->currentIndex(); + m_alphabetNameCombo->setCurrentIndex(m_alphabetNameCombo->findText(QString::fromUtf8(QUACKLE_ALPHABET_PARAMETERS->alphabetName().c_str()))); m_themeNameCombo->setCurrentIndex(m_themeNameCombo->findText(m_themeName)); m_boardNameCombo->setCurrentIndex(m_boardNameCombo->findText(QuackleIO::Util::uvStringToQString(QUACKLE_BOARD_PARAMETERS->name()))); + m_lastGoodBoardValue = m_boardNameCombo->currentIndex(); + m_copyrightLabel->setText(QString::fromUtf8(QUACKLE_LEXICON_PARAMETERS->copyrightString().c_str())); } void Settings::preInitialize() @@ -198,7 +197,8 @@ void Settings::initialize() CustomQSettings settings; QUACKLE_DATAMANAGER->setBackupLexicon("twl06"); - QUACKLE_DATAMANAGER->setDataDirectory(m_dataDir.toStdString()); + QUACKLE_DATAMANAGER->setAppDataDirectory(m_appDataDir.toStdString()); + QUACKLE_DATAMANAGER->setUserDataDirectory(m_userDataDir.toStdString()); QString lexiconName = settings.value("quackle/settings/lexicon-name", QString("twl06")).toString(); @@ -206,50 +206,98 @@ void Settings::initialize() if (lexiconName == "cswfeb07") lexiconName = "cswapr07"; - setQuackleToUseLexiconName(QuackleIO::Util::qstringToStdString(lexiconName)); - setQuackleToUseAlphabetName(QuackleIO::Util::qstringToStdString(settings.value("quackle/settings/alphabet-name", QString("english")).toString())); + setQuackleToUseLexiconName(lexiconName); + setQuackleToUseAlphabetName(settings.value("quackle/settings/alphabet-name", QString("english")).toString()); setQuackleToUseThemeName(settings.value("quackle/settings/theme-name", QString("traditional")).toString()); setQuackleToUseBoardName(settings.value("quackle/settings/board-name", QString("")).toString()); } -void Settings::setQuackleToUseLexiconName(const string &lexiconName) +void Settings::buildGaddag(const string &filename) +{ + GaddagFactory factory((UVString())); + Quackle::LetterString word; + + pushIndex(factory, word, 1); + factory.generate(); + factory.writeIndex(filename); +} + +void Settings::pushIndex(GaddagFactory &factory, Quackle::LetterString &word, int index) { - if (QUACKLE_LEXICON_PARAMETERS->lexiconName() != lexiconName) + unsigned int p; + Quackle::Letter letter; + bool t; + bool lastchild; + bool british; + int playability; + + do { - QUACKLE_LEXICON_PARAMETERS->setLexiconName(lexiconName); + QUACKLE_LEXICON_PARAMETERS->dawgAt(index, p, letter, t, lastchild, british, playability); + word.push_back(letter); + if (t) + factory.pushWord(word); + if (p) + pushIndex(factory, word, p); + index++; + word.pop_back(); + } while (!lastchild); +} - string gaddagFile = Quackle::LexiconParameters::findDictionaryFile(lexiconName + ".gaddag"); - if (gaddagFile.empty()) - { - UVcout << "Gaddag for lexicon '" << lexiconName << "' does not exist." << endl; - QUACKLE_LEXICON_PARAMETERS->unloadGaddag(); - } - else - QUACKLE_LEXICON_PARAMETERS->loadGaddag(gaddagFile); +void Settings::setQuackleToUseLexiconName(const QString &lexiconName) +{ + string lexiconNameStr = lexiconName.toStdString(); + if (QUACKLE_LEXICON_PARAMETERS->lexiconName() != lexiconNameStr) + { + QUACKLE_LEXICON_PARAMETERS->setLexiconName(lexiconNameStr); - string dawgFile = Quackle::LexiconParameters::findDictionaryFile(lexiconName + ".dawg"); + string dawgFile = Quackle::LexiconParameters::findDictionaryFile(lexiconNameStr + ".dawg"); if (dawgFile.empty()) { - UVcout << "Dawg for lexicon '" << lexiconName << "' does not exist." << endl; + UVcout << "Dawg for lexicon '" << lexiconNameStr << "' does not exist." << endl; QUACKLE_LEXICON_PARAMETERS->unloadDawg(); } else QUACKLE_LEXICON_PARAMETERS->loadDawg(dawgFile); - QUACKLE_STRATEGY_PARAMETERS->initialize(lexiconName); + if (!QUACKLE_LEXICON_PARAMETERS->hasDawg()) + { + QUACKLE_LEXICON_PARAMETERS->unloadGaddag(); + return; + } + + string gaddagFile = Quackle::LexiconParameters::findDictionaryFile(lexiconNameStr + ".gaddag"); + if (gaddagFile.empty()) + { + UVcout << "Gaddag for lexicon '" << lexiconNameStr << "' does not exist." << endl; + QUACKLE_LEXICON_PARAMETERS->unloadGaddag(); + } + else + QUACKLE_LEXICON_PARAMETERS->loadGaddag(gaddagFile); + + // if (!QUACKLE_LEXICON_PARAMETERS->hasGaddag()) + // { + // gaddagFile = QUACKLE_DATAMANAGER->makeDataFilename("lexica", lexiconNameStr + ".gaddag", true); + // buildGaddag(gaddagFile); + // QUACKLE_LEXICON_PARAMETERS->loadGaddag(gaddagFile); + // } + + QUACKLE_STRATEGY_PARAMETERS->initialize(lexiconNameStr); + m_copyrightLabel->setText(QString::fromUtf8(QUACKLE_LEXICON_PARAMETERS->copyrightString().c_str())); } } -void Settings::setQuackleToUseAlphabetName(const string &alphabetName) +void Settings::setQuackleToUseAlphabetName(const QString &alphabetName) { - if (QUACKLE_ALPHABET_PARAMETERS->alphabetName() != alphabetName) + string alphabetNameStr = alphabetName.toStdString(); + if (QUACKLE_ALPHABET_PARAMETERS->alphabetName() != alphabetNameStr) { - QString alphabetFile = QuackleIO::Util::stdStringToQString(Quackle::AlphabetParameters::findAlphabetFile(alphabetName + ".quackle_alphabet")); + QString alphabetFileStr = QuackleIO::Util::stdStringToQString(Quackle::AlphabetParameters::findAlphabetFile(alphabetNameStr)); QuackleIO::FlexibleAlphabetParameters *flexure = new QuackleIO::FlexibleAlphabetParameters; - flexure->setAlphabetName(alphabetName); - if (flexure->load(alphabetFile)) + flexure->setAlphabetName(alphabetNameStr); + if (flexure->load(alphabetFileStr)) { if (flexure->length() != QUACKLE_ALPHABET_PARAMETERS->length() && QUACKLE_ALPHABET_PARAMETERS->alphabetName() != "default") { @@ -269,11 +317,13 @@ void Settings::setQuackleToUseAlphabetName(const string &alphabetName) void Settings::setQuackleToUseThemeName(const QString &themeName) { m_themeName = themeName; - QString themeFile = m_dataDir + "/themes/" + themeName + ".ini"; + QString themeFile = m_userDataDir + "/themes/" + themeName + ".ini"; + if (!QFile::exists(themeFile)) + themeFile = m_appDataDir + "/themes/" + themeName + ".ini"; if (!QFile::exists(themeFile)) { m_themeName = "traditional"; - themeFile = m_dataDir + "/themes/traditional.ini"; + themeFile = m_appDataDir + "/themes/traditional.ini"; } PixmapCacher::self()->readTheme(themeFile); } @@ -300,19 +350,34 @@ void Settings::setQuackleToUseBoardName(const QString &boardName) void Settings::lexiconChanged(const QString &lexiconName) { - string lexiconNameString = QuackleIO::Util::qstringToStdString(lexiconName); - setQuackleToUseLexiconName(lexiconNameString); + QString lexicon = lexiconName; + if (lexicon.endsWith("*")) + lexicon.truncate(lexicon.size() - 1); + if (m_lexiconNameCombo->currentIndex() == m_lexiconNameCombo->count() - 1) + { + editLexicon(); + if (m_lexiconNameCombo->currentIndex() == m_lexiconNameCombo->count() - 1 && + m_lexiconNameCombo->currentIndex() != 0) + m_lexiconNameCombo->setCurrentIndex(m_lastGoodLexiconValue); + return; + } + setQuackleToUseLexiconName(lexicon); + m_lastGoodLexiconValue = m_lexiconNameCombo->currentIndex(); CustomQSettings settings; - settings.setValue("quackle/settings/lexicon-name", lexiconName); + settings.setValue("quackle/settings/lexicon-name", lexicon); emit refreshViews(); } void Settings::alphabetChanged(const QString &alphabetName) { - string alphabetNameString = QuackleIO::Util::qstringToStdString(alphabetName); - setQuackleToUseAlphabetName(alphabetNameString); + if (m_alphabetNameCombo->currentIndex() == m_alphabetNameCombo->count() - 1) + { + editAlphabet(); + return; + } + setQuackleToUseAlphabetName(alphabetName); CustomQSettings settings; settings.setValue("quackle/settings/alphabet-name", alphabetName); @@ -322,6 +387,11 @@ void Settings::alphabetChanged(const QString &alphabetName) void Settings::themeChanged(const QString &themeName) { + if (m_themeNameCombo->currentIndex() == m_themeNameCombo->count() - 1) + { + editTheme(); + return; + } setQuackleToUseThemeName(themeName); CustomQSettings settings; @@ -332,6 +402,14 @@ void Settings::themeChanged(const QString &themeName) void Settings::boardChanged(const QString &boardName) { + if (m_boardNameCombo->currentIndex() == m_boardNameCombo->count() - 1) + { + addBoard(); + if (m_boardNameCombo->currentIndex() == m_boardNameCombo->count() - 1 && + m_boardNameCombo->currentIndex() != 0) + m_boardNameCombo->setCurrentIndex(m_lastGoodBoardValue); + return; + } CustomQSettings settings; settings.setValue("quackle/settings/board-name", boardName); @@ -358,6 +436,7 @@ void Settings::addBoard() (const uchar *)boardParameterStream.str().data(), boardParameterStream.str().size()); settings.setValue(boardName, QVariant(boardParameterBytes)); + m_boardNameCombo->setCurrentIndex(-1); boardChanged(boardName); } else @@ -391,35 +470,12 @@ void Settings::editBoard() boardChanged(newBoardName); } PixmapCacher::self()->invalidate(); -} - -void Settings::deleteBoard() -{ - int oldIndex = m_boardNameCombo->currentIndex(); - QString boardName = m_boardNameCombo->currentText(); - QString message = "Do you really want to delete the game board \""; - message += boardName; - message += "\"?"; - if (QMessageBox::warning(NULL, QString("Confirm Deletion"), message, - QMessageBox::Yes | QMessageBox::Default, - QMessageBox::No | QMessageBox::Escape) == QMessageBox::Yes) - { - CustomQSettings settings; - settings.beginGroup("quackle/boardparameters"); - settings.remove(boardName); - loadBoardNameCombo(); - if (oldIndex != 0) - oldIndex--; - m_boardNameCombo->setCurrentIndex(oldIndex); - boardChanged(m_boardNameCombo->currentText()); - } + loadBoardNameCombo(); + emit refreshViews(); } void Settings::loadBoardNameCombo() { - if (m_lexiconNameCombo == 0) - return; - while (m_boardNameCombo->count() > 0) m_boardNameCombo->removeItem(0); @@ -428,26 +484,100 @@ void Settings::loadBoardNameCombo() QStringList boardNames = settings.childKeys(); boardNames.sort(); m_boardNameCombo->addItems(boardNames); + m_boardNameCombo->addItem("Add new board..."); settings.endGroup(); QString currentItem = settings.value("quackle/settings/board-name", QString("")).toString(); - m_boardNameCombo->setCurrentIndex(m_boardNameCombo->findText(currentItem)); + int currentItemIndex = m_boardNameCombo->findText(currentItem); + if (m_boardNameCombo->count() > 0 && currentItemIndex < 0) + currentItemIndex = 0; + m_boardNameCombo->setCurrentIndex(currentItemIndex); +} + +void Settings::editLexicon() +{ + QString name = m_lexiconNameCombo->currentText(); + if (name.endsWith("*")) + name.truncate(name.size() - 1); + if (m_lexiconNameCombo->currentIndex() == m_lexiconNameCombo->count() - 1) + name = ""; + LexiconDialog dialog(this, name); + if (dialog.exec()) + { + populateComboFromFilenames(m_lexiconNameCombo, "lexica", ".dawg", "lexicon"); + qApp->processEvents(); + if (dialog.itemWasDeleted()) + { + m_lexiconNameCombo->setCurrentIndex(m_lexiconNameCombo->findText(name)); + QUACKLE_LEXICON_PARAMETERS->setLexiconName(""); // force lexicon to reload + QUACKLE_LEXICON_PARAMETERS->unloadAll(); + if (m_lexiconNameCombo->currentIndex() != -1) + setQuackleToUseLexiconName(name); + } + else if (!dialog.lexiconName().isEmpty()) + { + QUACKLE_LEXICON_PARAMETERS->setLexiconName(""); // force lexicon to reload + QUACKLE_LEXICON_PARAMETERS->unloadAll(); + setQuackleToUseLexiconName(dialog.lexiconName()); + m_lexiconNameCombo->setCurrentIndex(m_lexiconNameCombo->findText(name + "*")); + } + load(); + } +} - m_editBoard->setEnabled(boardNames.count() > 0); - m_deleteBoard->setEnabled(boardNames.count() > 0); +void Settings::editAlphabet() +{ +#if 0 + QString name = m_alphabetNameCombo->currentText(); + if (m_alphabetNameCombo->currentIndex() == m_alphabetNameCombo->count() - 1) + name = ""; + AlphabetDialog dialog(this); + if (dialog.exec()) + { + populateComboFromFilenames(m_alphabetNameCombo, "alphabets", ".quackle_alphabet", "alphabet"); + load(); + } +#endif // 0 +} + +void Settings::editTheme() +{ +#if 0 + QString name = m_themeNameCombo->currentText(); + if (m_themeNameCombo->currentIndex() == m_themeNameCombo->count() - 1) + name = ""; + ThemeDialog dialog(this); + if (dialog.exec()) + { + populateThemeFromFilenames(m_themeNameCombo, "themes", "theme"); + load(); + } +#endif // 0 } -void Settings::populateListFromFilenames(QStringList& list, const QString &path) +void Settings::populateComboFromFilenames(QComboBox* combo, const QString &path, const QString &extension, const QString &label) { - QDir dir(path); - QStringList fileList = dir.entryList(QDir::Files | QDir::Readable, QDir::Name); - QStringListIterator i(fileList); + while (combo->count() > 0) + combo->removeItem(0); + + QStringList fileList; + QDir dir(self()->m_appDataDir); + if (dir.cd(path)) + fileList << dir.entryList(QDir::Files | QDir::Readable, QDir::Name); + dir = QDir(self()->m_userDataDir); + if (dir.cd(path)) + fileList << dir.entryList(QDir::Files | QDir::Readable, QDir::Name); + + QStringList::iterator i; QString fileName; + QStringList list; int periodPos; - while (i.hasNext()) + for (i = fileList.begin(); i != fileList.end(); ++i) { - fileName = i.next(); + fileName = *i; + if (!fileName.endsWith(extension)) + continue; periodPos = fileName.indexOf('.'); if (periodPos) { @@ -455,5 +585,21 @@ void Settings::populateListFromFilenames(QStringList& list, const QString &path) list << fileName; } } - list.removeDuplicates(); + + for (i = list.begin(); i != list.end(); ++i) + { + for (QStringList::iterator j = i + 1; j != list.end(); ++j) + { + if (*i == *j) + { + *i = *i + "*"; + list.erase(j); + break; + } + } + } + + combo->addItems(list); + if (label.size() > 0) + combo->addItem(QString(tr("Add new ")).append(path).append("...")); } diff --git a/quacker/settings.h b/quacker/settings.h index 785b726..ef3449e 100644 --- a/quacker/settings.h +++ b/quacker/settings.h @@ -24,9 +24,12 @@ #include <QWidget> #include <QSettings> +#include "quackleio/gaddagfactory.h" + class QComboBox; class QCheckBox; class QPushButton; +class QLabel; using namespace std; @@ -39,6 +42,9 @@ public: static Settings *self(); + // load up an item list based on a list of filenames + static void populateComboFromFilenames(QComboBox* combo, const QString &path, const QString &extension, const QString &label); + signals: void refreshViews(); @@ -64,10 +70,13 @@ protected slots: void addBoard(); void editBoard(); - void deleteBoard(); - void setQuackleToUseLexiconName(const string &lexiconName); - void setQuackleToUseAlphabetName(const string &alphabetName); + void editLexicon(); + void editAlphabet(); + void editTheme(); + + void setQuackleToUseLexiconName(const QString &lexiconName); + void setQuackleToUseAlphabetName(const QString &alphabetName); void setQuackleToUseThemeName(const QString &themeName); void setQuackleToUseBoardName(const QString &lexiconName); @@ -76,20 +85,25 @@ protected: QComboBox *m_alphabetNameCombo; QComboBox *m_themeNameCombo; QComboBox *m_boardNameCombo; - QPushButton *m_addBoard; + QPushButton *m_editLexicon; + QPushButton *m_editAlphabet; + QPushButton *m_editTheme; QPushButton *m_editBoard; - QPushButton *m_deleteBoard; - QString m_dataDir; + QLabel *m_copyrightLabel; + QString m_appDataDir; + QString m_userDataDir; QString m_themeName; private: // populate the popup based on what's in QSettings void loadBoardNameCombo(); - // load up an item list based on a list of filenames - void populateListFromFilenames(QStringList& list, const QString &path); - + void buildGaddag(const string &filename); + void pushIndex(GaddagFactory &factory, Quackle::LetterString &word, int index); + static Settings *m_self; + int m_lastGoodLexiconValue; + int m_lastGoodBoardValue; }; #endif |