diff options
author | John Fultz <jfultz@wolfram.com> | 2015-10-10 19:09:36 -0500 |
---|---|---|
committer | John Fultz <jfultz@wolfram.com> | 2015-10-10 19:09:36 -0500 |
commit | 69e3dcefb882c743b136df8e5c81b4182b135f6b (patch) | |
tree | faabb8c691da11067297df8d870c0393a91c8a7f | |
parent | 81554a201cc5e0748110add6eca05cc16c18850c (diff) |
Progress on the lexicon dialog.
Now prints better stats. Now loads the
dictionary you're editing. Now disables the
Delete button at appropriate times.
-rw-r--r-- | datamanager.cpp | 6 | ||||
-rw-r--r-- | datamanager.h | 3 | ||||
-rw-r--r-- | lexiconparameters.cpp | 5 | ||||
-rw-r--r-- | lexiconparameters.h | 1 | ||||
-rw-r--r-- | quacker/lexicondialog.cpp | 36 | ||||
-rw-r--r-- | quacker/lexicondialog.h | 4 | ||||
-rw-r--r-- | quacker/settings.cpp | 30 | ||||
-rw-r--r-- | quacker/settings.h | 2 | ||||
-rw-r--r-- | quackleio/dawgfactory.cpp | 37 | ||||
-rw-r--r-- | quackleio/dawgfactory.h | 8 |
10 files changed, 113 insertions, 19 deletions
diff --git a/datamanager.cpp b/datamanager.cpp index eb65afd..916610a 100644 --- a/datamanager.cpp +++ b/datamanager.cpp @@ -156,6 +156,12 @@ string DataManager::findDataFile(const string &subDirectory, const string &file) return fname; } +bool DataManager::hasUserDataFile(const string &subDirectory, const string &file) +{ + string fname = makeDataFilename(subDirectory, file, true); + return fileExists(fname); +} + string DataManager::makeDataFilename(const string &subDirectory, const string &lexicon, const string &file, bool user) { return (user ? m_userDataDirectory : m_appDataDirectory) + "/" + subDirectory + "/" + lexicon + "/" + file; diff --git a/datamanager.h b/datamanager.h index 196d525..75bce54 100644 --- a/datamanager.h +++ b/datamanager.h @@ -105,6 +105,9 @@ public: // Returns empty string if the file is not found. string findDataFile(const string &subDirectory, const string &file); + // Returns true if the data file is in user-land. + bool hasUserDataFile(const string &subDirectory, const string &file); + // returns similarly-named file string makeDataFilename(const string &subDirectory, const string &lexicon, const string &file, bool user); string makeDataFilename(const string &subDirectory, const string &file, bool user); diff --git a/lexiconparameters.cpp b/lexiconparameters.cpp index 9da3b70..bc10773 100644 --- a/lexiconparameters.cpp +++ b/lexiconparameters.cpp @@ -224,6 +224,11 @@ string LexiconParameters::findDictionaryFile(const string &lexicon) return QUACKLE_DATAMANAGER->findDataFile("lexica", lexicon); } +bool LexiconParameters::hasUserDictionaryFile(const string &lexicon) +{ + return QUACKLE_DATAMANAGER->hasUserDataFile("lexica", lexicon); +} + UVString LexiconParameters::hashString(bool shortened) const { const char hex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; diff --git a/lexiconparameters.h b/lexiconparameters.h index 9f34be6..4eda4f3 100644 --- a/lexiconparameters.h +++ b/lexiconparameters.h @@ -68,6 +68,7 @@ public: // finds a file in the lexica data directory static string findDictionaryFile(const string &lexicon); + static bool hasUserDictionaryFile(const string &lexicon); // a convenience field; this is unused by libquackle string lexiconName() const { return m_lexiconName; }; diff --git a/quacker/lexicondialog.cpp b/quacker/lexicondialog.cpp index a7566c6..e11ae41 100644 --- a/quacker/lexicondialog.cpp +++ b/quacker/lexicondialog.cpp @@ -103,9 +103,21 @@ LexiconDialog::LexiconDialog(QWidget *parent, const QString &originalName) : QDi Settings::populateComboFromFilenames(m_alphabetCombo, "alphabets", ""); alphabetChanged(m_alphabetCombo->currentText()); - updateLexiconInformation(); - // sync game board with control states and draw board + string dawgFileName = originalName.toStdString() + ".dawg"; + QString dawgFullFileName; + if (!originalName.isEmpty()) + dawgFullFileName = QString::fromStdString(Quackle::LexiconParameters::findDictionaryFile(dawgFileName)); + + if (!dawgFullFileName.isEmpty()) + { + m_deleteLexicon->setEnabled(Quackle::LexiconParameters::hasUserDictionaryFile(dawgFileName)); + addWordsFromDawgFile(dawgFullFileName); + } + else + m_deleteLexicon->setEnabled(false); + + updateLexiconInformation(); } LexiconDialog::~LexiconDialog() @@ -134,9 +146,9 @@ void LexiconDialog::addWordsFromFile() for (QList<QString>::const_iterator it = files.begin(); it != files.end(); it++) { if (it->endsWith(".dawg", Qt::CaseInsensitive)) - addWordsFromDawgFile(*it, m_alphabetCombo->currentText()); + addWordsFromDawgFile(*it); else - addWordsFromTextFile(*it, m_alphabetCombo->currentText()); + addWordsFromTextFile(*it); } updateLexiconInformation(); } @@ -149,7 +161,7 @@ void LexiconDialog::alphabetChanged(const QString &alphabet) m_alphabetFileName = QString::fromStdString(AlphabetParameters::findAlphabetFile(QuackleIO::Util::qstringToStdString(alphabet))); } -void LexiconDialog::addWordsFromDawgFile(const QString &dawgfile, const QString &alphabetfile) +void LexiconDialog::addWordsFromDawgFile(const QString &dawgfile) { if (!m_wordFactory) m_wordFactory = new DawgFactory(m_alphabetFileName); @@ -185,7 +197,7 @@ void LexiconDialog::addWordsFromDawgRecursive(const LexiconParameters &lexParams } while (!lastchild); } -void LexiconDialog::addWordsFromTextFile(const QString &textFile, const QString &alphabetfile) +void LexiconDialog::addWordsFromTextFile(const QString &textFile) { if (!m_wordFactory) m_wordFactory = new DawgFactory(m_alphabetFileName); @@ -224,14 +236,20 @@ void LexiconDialog::accept() void LexiconDialog::updateLexiconInformation() { int wordCount = m_wordFactory ? m_wordFactory->wordCount() : 0; - QByteArray hash = m_wordFactory ? QByteArray(m_wordFactory->hashBytes(), 16).toHex() : ""; + QByteArray hash = (m_wordFactory && wordCount) ? QByteArray(m_wordFactory->hashBytes(), 16).toHex() : ""; QString text; + QString lengthText; + if (m_wordFactory) + lengthText = QString::fromStdString(m_wordFactory->letterCountString()); + text.append(tr("File name: ")); text.append(tr("\n\nFile size: ")); text.append(tr("\n\nWord count: ")); text.append(QString("%L1").arg(wordCount)); - text.append(tr("\n\nLexicon hash: ")); - text.append(hash); + text.append("\n"); + text.append(lengthText); + text.append(tr("\nLexicon hash: ")); + text.append(hash.left(8)); m_lexiconInformation->setText(text); } diff --git a/quacker/lexicondialog.h b/quacker/lexicondialog.h index 4df6138..39cd546 100644 --- a/quacker/lexicondialog.h +++ b/quacker/lexicondialog.h @@ -52,9 +52,9 @@ protected slots: void alphabetChanged(const QString &); protected: - void addWordsFromDawgFile(const QString &dawgfile, const QString &alphabetfile); + void addWordsFromDawgFile(const QString &dawgfile); void addWordsFromDawgRecursive(const LexiconParameters &lexParams, Quackle::LetterString &word, int index); - void addWordsFromTextFile(const QString &textFile, const QString &alphabetfile); + void addWordsFromTextFile(const QString &textFile); private: QLineEdit *m_lexiconName; diff --git a/quacker/settings.cpp b/quacker/settings.cpp index ce8583f..3319955 100644 --- a/quacker/settings.cpp +++ b/quacker/settings.cpp @@ -172,9 +172,11 @@ void Settings::createGUI() void Settings::load() { m_lexiconNameCombo->setCurrentIndex(m_lexiconNameCombo->findText(QuackleIO::Util::stdStringToQString(QUACKLE_LEXICON_PARAMETERS->lexiconName()))); + m_lastGoodLexiconValue = m_lexiconNameCombo->currentIndex(); m_alphabetNameCombo->setCurrentIndex(m_alphabetNameCombo->findText(QuackleIO::Util::stdStringToQString(QUACKLE_ALPHABET_PARAMETERS->alphabetName()))); 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(); } void Settings::preInitialize() @@ -343,9 +345,13 @@ void Settings::lexiconChanged(const QString &lexiconName) 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(lexiconName); + m_lastGoodLexiconValue = m_lexiconNameCombo->currentIndex(); CustomQSettings settings; settings.setValue("quackle/settings/lexicon-name", lexiconName); @@ -388,6 +394,9 @@ 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; @@ -530,14 +539,14 @@ void Settings::populateComboFromFilenames(QComboBox* combo, const QString &path, if (dir.cd(path)) fileList << dir.entryList(QDir::Files | QDir::Readable, QDir::Name); - QStringListIterator i(fileList); + 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; periodPos = fileName.indexOf('.'); if (periodPos) { @@ -545,7 +554,20 @@ void Settings::populateComboFromFilenames(QComboBox* combo, const QString &path, list << fileName; } } - list.removeDuplicates(); + + for (i = fileList.begin(); i != fileList.end(); ++i) + { + QStringList::iterator j = i; + for (++j; j != fileList.end(); ++j) + { + if (*i == *j) + { + *i = "* " + *i; + list.erase(j); + break; + } + } + } combo->addItems(list); if (label.size() > 0) diff --git a/quacker/settings.h b/quacker/settings.h index fab2f3f..7c5738e 100644 --- a/quacker/settings.h +++ b/quacker/settings.h @@ -100,6 +100,8 @@ private: void pushIndex(GaddagFactory &factory, Quackle::LetterString &word, int index); static Settings *m_self; + int m_lastGoodLexiconValue; + int m_lastGoodBoardValue; }; #endif diff --git a/quackleio/dawgfactory.cpp b/quackleio/dawgfactory.cpp index e7ada85..362dfdc 100644 --- a/quackleio/dawgfactory.cpp +++ b/quackleio/dawgfactory.cpp @@ -17,6 +17,8 @@ */ +#include <iomanip> +#include <ios> #include <iostream> #include <QtCore> #include <QCryptographicHash> @@ -184,6 +186,34 @@ void DawgFactory::writeIndex(const UVString& filename) } } +int DawgFactory::wordCount() const +{ + m_countsByLength.resize(0); + return m_root.wordCount(0, m_countsByLength); +} + +string DawgFactory::letterCountString() const +{ + ostringstream str; + if (m_countsByLength.size() < 16) + m_countsByLength.resize(16, 0); + str << "2s: " << std::setw(7) << std::right << std::setfill(' ') << m_countsByLength[2]; + str << "\t6s: " << std::setw(7) << std::right << std::setfill(' ') << m_countsByLength[6]; + str << "\t10s: " << std::setw(7) << std::right << std::setfill(' ') << m_countsByLength[10]; + str << "\t14s: " << std::setw(7) << std::right << std::setfill(' ') << m_countsByLength[14]; + str << "\n3s: " << std::setw(7) << std::right << std::setfill(' ') << m_countsByLength[3]; + str << "\t7s: " << std::setw(7) << std::right << std::setfill(' ') << m_countsByLength[7]; + str << "\t11s: " << std::setw(7) << std::right << std::setfill(' ') << m_countsByLength[11]; + str << "\t15s: " << std::setw(7) << std::right << std::setfill(' ') << m_countsByLength[15]; + str << "\n4s: " << std::setw(7) << std::right << std::setfill(' ') << m_countsByLength[4]; + str << "\t8s: " << std::setw(7) << std::right << std::setfill(' ') << m_countsByLength[8]; + str << "\t12s: " << std::setw(7) << std::right << std::setfill(' ') << m_countsByLength[12]; + str << "\n5s: " << std::setw(7) << std::right << std::setfill(' ') << m_countsByLength[5]; + str << "\t9s: " << std::setw(7) << std::right << std::setfill(' ') << m_countsByLength[9]; + str << "\t13s: " << std::setw(7) << std::right << std::setfill(' ') << m_countsByLength[13]; + str << "\n"; + return str.str(); +} void DawgFactory::Node::print(vector< Node* >& nodelist) @@ -287,11 +317,14 @@ bool DawgFactory::Node::equals(const Node &n) const return true; } -int DawgFactory::Node::wordCount() const +int DawgFactory::Node::wordCount(unsigned int depth, vector<unsigned int> &countsByLength) const { int wordCount = ((playability == 0) ? 0 : 1); + if (countsByLength.size() < depth + 1) + countsByLength.resize(depth + 1, 0); + countsByLength[depth] += wordCount; for (size_t i = 0; i < children.size(); i++) - wordCount += children[i].wordCount(); + wordCount += children[i].wordCount(depth + 1, countsByLength); return wordCount; } diff --git a/quackleio/dawgfactory.h b/quackleio/dawgfactory.h index 1a1aa7d..8dd6e03 100644 --- a/quackleio/dawgfactory.h +++ b/quackleio/dawgfactory.h @@ -19,6 +19,7 @@ #ifndef QUACKLE_DAWGFACTORY_H #define QUACKLE_DAWGFACTORY_H +#include <string> #include <vector> #include "flexiblealphabet.h" @@ -29,7 +30,8 @@ public: DawgFactory(const QString &alphabetFile); ~DawgFactory(); - int wordCount() const { return m_root.wordCount(); }; + int wordCount() const; + string letterCountString() const; int nodeCount() const { return m_nodelist.size(); }; int encodableWords() const { return m_encodableWords; }; int unencodableWords() const { return m_unencodableWords; }; @@ -50,7 +52,7 @@ private: void print(vector< Node* >& m_nodelist); int letterSum() const; - int wordCount() const; + int wordCount(unsigned int depth, vector<unsigned int> &countsByLength) const; bool equals(const Node &n) const; Quackle::Letter c; @@ -65,6 +67,7 @@ private: mutable bool sumexplored; mutable int sum; + mutable vector<int> counts; bool deleted; Node* cloneof; @@ -75,6 +78,7 @@ private: int m_unencodableWords; int m_duplicateWords; vector< Node* > m_nodelist; + mutable vector<unsigned int> m_countsByLength; Quackle::AlphabetParameters *m_alphas; Node m_root; union { |