summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--datamanager.cpp6
-rw-r--r--datamanager.h3
-rw-r--r--lexiconparameters.cpp5
-rw-r--r--lexiconparameters.h1
-rw-r--r--quacker/lexicondialog.cpp36
-rw-r--r--quacker/lexicondialog.h4
-rw-r--r--quacker/settings.cpp30
-rw-r--r--quacker/settings.h2
-rw-r--r--quackleio/dawgfactory.cpp37
-rw-r--r--quackleio/dawgfactory.h8
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 {