diff --git a/.gitignore b/.gitignore index 73143d4c..ff61045e 100644 --- a/.gitignore +++ b/.gitignore @@ -31,30 +31,36 @@ qrc_*.* *.autosave # the main program itself -nixnote nixnote2 -#user files +# user files *.pro.* -#compiled translations +# compiled translations translations/*.qm -#Makefiles +# Makefiles Makefile Makefile.Debug Makefile.Release -#KDE workfile +# KDE workfile .directory /.project -#eclipse files +# eclipse files .cproject .settings cmake-build-debug/ -.idea/ +build/ -#QMake file +# idea +.idea/workspace.xml +.idea/misc.xml +.idea/tasks.xml +.idea/dictionaries +.idea/watcherTasks.xml + +# QMake file .qmake.stash diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 00000000..a55e7a17 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/nixnote2.xml b/.idea/runConfigurations/nixnote2.xml new file mode 100644 index 00000000..f208313e --- /dev/null +++ b/.idea/runConfigurations/nixnote2.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/cmdtools/cmdlinetool.cpp b/cmdtools/cmdlinetool.cpp index 011adf0f..441ccb61 100644 --- a/cmdtools/cmdlinetool.cpp +++ b/cmdtools/cmdlinetool.cpp @@ -773,7 +773,7 @@ int CmdLineTool::sync() { sql.exec("Select * from sqlite_master where type='table' and name='NoteTable';"); if (!sql.next()) { NoteModel model(this); - model.createTable(); + model.createNoteTable(); } sql.finish(); diff --git a/deploy-step.sh b/deploy-step.sh new file mode 100755 index 00000000..71806ea8 --- /dev/null +++ b/deploy-step.sh @@ -0,0 +1,25 @@ +#!/bin/sh + +# simple script which can be used as deployment step in qt creator +# $1 is expected to be target directory + + +echo Deploying `pwd` to $1 + +# copy folders ... +cp -rf \ + help \ + images \ + java \ + qss \ + translations \ + $1 + +# ... and files required for execution +cp -f \ + changelog.txt \ + license.html \ + shortcuts.txt \ + $1 + +echo Finished deployment.. \ No newline at end of file diff --git a/filters/filterengine.cpp b/filters/filterengine.cpp index 77673e93..28c7a4c4 100644 --- a/filters/filterengine.cpp +++ b/filters/filterengine.cpp @@ -41,8 +41,126 @@ FilterEngine::FilterEngine(QObject *parent) : } -void FilterEngine::filter(FilterCriteria *newCriteria, QList *results) { +// prepare SQL query for selection by tag +// searched string is in "searchStr" +// relevance==0 means we a doing primary search +// relevance>0 means we are doing relevance update search +// "negativeSearch" may only be passed for relevance==0 and means negative search +// +void setupTagSelectionQuery(NSqlQuery &sql, QString searchStr, int relevance, bool negativeSearch) { + + // 0: search (may then be positive or negative) + // >0: relevance update + bool isRelevanceUpdate = relevance > 0; + + // is it wildcard search? + bool isWildcardSearch = searchStr.contains("*"); + // this is a bit hack/tinkering - in search we donÄt do automatic right truncating for tags + // but for relevance update we do for "title", so let do it also for tags + if (isRelevanceUpdate && !isWildcardSearch) { + searchStr = searchStr + QString("*"); + isWildcardSearch = true; + } + + QString cmdStr; + QString selectionPart; + if (!isWildcardSearch) { + selectionPart = QString( + "(" + "select lid from datastore where key=:notetagkey" + " and data in (select lid from DataStore where data=:tagname and key=:tagnamekey)" + ")" + ); + } else { + selectionPart = QString( + "(" + "select lid from datastore where key=:notetagkey" + " and data in (select lid from DataStore where data like :tagname and key=:tagnamekey)" + ")" + ); + + searchStr = searchStr.replace("*", "%"); + } + if (!isRelevanceUpdate) { + // positive search: filter out records where tag is not found => "not" + // negative search: filter out record where tag IS found + QString negateStr = negativeSearch ? QString("") : QString("not"); + cmdStr = QString("delete from filter where lid ") + negateStr + QString(" in ") + selectionPart; + } else { + // update record where tag IS found + cmdStr = QString("update filter set relevance=relevance+:relevance where lid in ") + selectionPart; + } + + sql.prepare(cmdStr); + QLOG_DEBUG() << "Tag search query(" << searchStr + << ", relevance=" << relevance + << ", negative:" << negativeSearch + << "): " + cmdStr; + sql.bindValue(":tagname", searchStr); + sql.bindValue(":tagnamekey", TAG_NAME); + sql.bindValue(":notetagkey", NOTE_TAG_LID); + + if (isRelevanceUpdate) { + sql.bindValue(":relevance", relevance); + } +} + +// prepare SQL query for selection by note title +// searched string is in "searchStr" +// relevance==0 means we a doing primary search +// relevance>0 means we are doing relevance update search +// "negativeSearch" may only be passed for relevance==0 and means negative search +// +void setupTitleSelectionQuery(NSqlQuery &sql, QString searchStr, int relevance, bool negativeSearch) { + searchStr = searchStr.replace("*", "%"); + // 0: search (may then be positive or negative) + // >0: relevance update + bool isRelevanceUpdate = relevance > 0; + + // this may happen only if someone posts "intitle:" without term, which doesn't give much sense either + if (searchStr == "") { + searchStr = "*"; + } + searchStr = searchStr.replace("*", "%"); + + // default to right truncation + if (!searchStr.endsWith("%")) + searchStr = searchStr + QString("%"); + + // we also require left truncation, which is a bit unlucky (may also find what we don't expect) + if (!searchStr.startsWith("%")) + searchStr = QString("%") + searchStr; + + QString cmdStr; + QString selectionPart("(select lid from datastore where key=:key and data like :title)"); + + if (!isRelevanceUpdate) { + // positive search: filter out records (delete) where search term is not found in title => "not" + // negative search: filter out record where search term IS found in title => "" + QString negateStr = negativeSearch ? QString("") : QString("not"); + cmdStr = QString("delete from filter where lid ") + negateStr + QString(" in ") + selectionPart; + } else { + // update record where search term IS found in title + cmdStr = QString("update filter set relevance=relevance+:relevance where lid in ") + selectionPart; + } + sql.prepare(cmdStr); + QLOG_DEBUG() << "Title search query(" << searchStr + << ", relevance=" << relevance + << ", negative:" << negativeSearch + << "): " + cmdStr; + + + sql.bindValue(":key", NOTE_TITLE); + sql.bindValue(":title", searchStr); + + if (isRelevanceUpdate) { + sql.bindValue(":relevance", relevance); + } +} + + +void FilterEngine::filter(FilterCriteria *newCriteria, QList *results) { QLOG_TRACE_IN(); bool internalSearch = true; @@ -50,14 +168,15 @@ void FilterEngine::filter(FilterCriteria *newCriteria, QList *results) { QLOG_DEBUG() << "Purging filters"; sql.exec("delete from filter"); QLOG_DEBUG() << "Resetting filter table"; - sql.prepare("Insert into filter (lid) select lid from NoteTable where notebooklid not in (select lid from datastore where key=:closedNotebooks)"); + sql.prepare("Insert into filter (lid,relevance) " + "select lid,0 from NoteTable where notebooklid not in " + "(select lid from datastore where key=:closedNotebooks)"); sql.bindValue(":closedNotebooks", NOTEBOOK_IS_CLOSED); sql.exec(); sql.finish(); QLOG_DEBUG() << "Reset complete"; - FilterCriteria *criteria = newCriteria; if (criteria == NULL) criteria = global.filterCriteria[global.filterPosition]; @@ -79,13 +198,14 @@ void FilterEngine::filter(FilterCriteria *newCriteria, QList *results) { QLOG_DEBUG() << "Filtering complete"; // Now, re-insert any pinned notes - sql.prepare("Insert into filter (lid) select lid from Datastore where key=:key and lid not in (select lid from filter)"); + sql.prepare("Insert into filter (lid,relevance) select lid,1 from Datastore " + "where key=:key and lid not in (select lid from filter)"); sql.bindValue(":key", NOTE_ISPINNED); sql.exec(); // Remove any selected notes that are not in the filter. NSqlQuery query(global.db); - QList goodLids; + QList goodLids; query.exec("select lid from filter;"); while (query.next()) { goodLids.append(query.value(0).toInt()); @@ -93,12 +213,12 @@ void FilterEngine::filter(FilterCriteria *newCriteria, QList *results) { query.finish(); if (internalSearch) { - // Remove any selected notes that are not in the filter. + // Remove any selected notes that are not in the filter. if (global.filterCriteria.size() > 0) { FilterCriteria *criteria = global.filterCriteria[global.filterPosition]; - QList selectedLids; + QList selectedLids; criteria->getSelectedNotes(selectedLids); - for (int i=selectedLids.size()-1; i>=0; i--) { + for (int i = selectedLids.size() - 1; i >= 0; i--) { if (!goodLids.contains(selectedLids[i])) selectedLids.removeAll(selectedLids[i]); } @@ -106,7 +226,7 @@ void FilterEngine::filter(FilterCriteria *newCriteria, QList *results) { } } else { results->clear(); - for (int i=0; icontains(goodLids[i])) { results->append(goodLids[i]); } @@ -671,37 +791,37 @@ void FilterEngine::splitSearchTerms(QStringList &words, QString search) { qint32 len = search.length(); char nextChar = ' '; bool quote = false; - for (qint32 i=0; i 0; i++) { + for (qint32 i = 0; i < search.length() && search.length() > 0; i++) { if (search[i] == '\0') { - search = search.remove(0,1); - i=-1; + search = search.remove(0, 1); + i = -1; } else { pos = search.indexOf(QChar('\0')); if (pos != -1) { words.append(search.left(pos).toLower()); - search.remove(0,pos); - i=-1; + search.remove(0, pos); + i = -1; } else { words.append(search.toLower()); search = ""; @@ -710,7 +830,7 @@ void FilterEngine::splitSearchTerms(QStringList &words, QString search) { } // Now that we have everything separated, we can remove the unneeded " marks - for (qint32 i=0; i=:weight and content match :word)") + - QString("and lid not in (select data from DataStore where key=:key and lid in ") + - QString("(select lid from SearchIndex where weight>=:weight2 and content match :word2))")); - sqlnegative.prepare(QString("Delete from filter where lid in ") + - QString("(select lid from SearchIndex where weight>=:weight and content match :word)") + - QString(" or lid in (select data from DataStore where key=:key and lid in ") + - QString("(select lid from SearchIndex where weight>=:weight2 and content match :word2))")); + sql.prepare( + "Delete from filter where lid not in " + "(select lid from SearchIndex where weight>=:weight and content match :word)" + "and lid not in (select data from DataStore where key=:key and lid in " + "(select lid from SearchIndex where weight>=:weight2 and content match :word2))"); + sqlnegative.prepare( + "Delete from filter where lid in " + "(select lid from SearchIndex where weight>=:weight and content match :word)" + " or lid in (select data from DataStore where key=:key and lid in " + "(select lid from SearchIndex where weight>=:weight2 and content match :word2))"); sql.bindValue(":weight", global.getMinimumRecognitionWeight()); sql.bindValue(":weight2", global.getMinimumRecognitionWeight()); @@ -740,114 +864,103 @@ void FilterEngine::filterSearchStringAll(QStringList list) { sqlnegative.bindValue(":weight2", global.getMinimumRecognitionWeight()); sqlnegative.bindValue(":key", RESOURCE_NOTE_LID); - for (qint32 i=0; i=:weight and content like :word) or lid in (select data from DataStore where lid in (select lid from SearchIndex where weight>:weight2 and content like :word2))"); + prefix.prepare( + "Delete from filter where lid in (select lid from SearchIndex where weight>=:weight " + "and content like :word) or lid in (select data from DataStore where lid in " + "(select lid from SearchIndex where weight>:weight2 and content like :word2))"); prefix.bindValue(":weight", global.getMinimumRecognitionWeight()); prefix.bindValue(":weight2", global.getMinimumRecognitionWeight()); prefix.bindValue(":word", string); prefix.bindValue(":word2", string); prefix.exec(); - } - else if (string.indexOf("_") >=0) { // underscore search. FTS doesn't do this. + } else if (string.indexOf("_") >= 0) { // underscore search. FTS doesn't do this. string = string.replace("_", "/_"); string = string.replace("*", "%"); if (!string.endsWith("%")) - string = string +QString("%"); + string = string + QString("%"); if (!string.startsWith("%")) string = QString("%") + string; NSqlQuery prefix(global.db); - prefix.prepare("Delete from filter where lid not in (select lid from SearchIndex where weight>=:weight and content like :word escape '/') and lid not in (select data from DataStore where key=:key and lid in (select lid from SearchIndex where weight>:weight2 and content like :word2 escape '/'))"); + prefix.prepare( + "Delete from filter where lid not in (select lid from SearchIndex where weight>=:weight " + "and content like :word escape '/') and " + "lid not in (select data from DataStore where key=:key and lid in (select lid from SearchIndex " + "where weight>:weight2 and content like :word2 escape '/'))"); prefix.bindValue(":weight", global.getMinimumRecognitionWeight()); prefix.bindValue(":weight2", global.getMinimumRecognitionWeight()); @@ -855,15 +968,17 @@ void FilterEngine::filterSearchStringAll(QStringList list) { prefix.bindValue(":word2", string); prefix.bindValue(":key", RESOURCE_NOTE_LID); prefix.exec(); - } - else if (string.indexOf("-") >=0) { // Hyphen search. FTS doesn't do this. + } else if (string.indexOf("-") >= 0) { // Hyphen search. FTS doesn't do this. string = string.replace("*", "%"); if (!string.endsWith("%")) - string = string +QString("%"); + string = string + QString("%"); if (!string.startsWith("%")) string = QString("%") + string; NSqlQuery prefix(global.db); - prefix.prepare("Delete from filter where lid not in (select lid from SearchIndex where weight>=:weight and content like :word) and lid not in (select data from DataStore where key=:key and lid in (select lid from SearchIndex where weight>:weight2 and content like :word2))"); + prefix.prepare( + "Delete from filter where lid not in (select lid from SearchIndex where weight>=:weight and content " + "like :word) and lid not in (select data from DataStore where key=:key and lid in (select lid " + "from SearchIndex where weight>:weight2 and content like :word2))"); prefix.bindValue(":weight", global.getMinimumRecognitionWeight()); prefix.bindValue(":weight2", global.getMinimumRecognitionWeight()); @@ -871,13 +986,15 @@ void FilterEngine::filterSearchStringAll(QStringList list) { prefix.bindValue(":word2", string); prefix.bindValue(":key", RESOURCE_NOTE_LID); prefix.exec(); - } - else if (string.startsWith("*")) { // Postfix search. FTS doesn't do this. + } else if (string.startsWith("*")) { // Postfix search. FTS doesn't do this. string = string.replace("*", "%"); if (!string.endsWith("%")) - string = string +QString("%"); + string = string + QString("%"); NSqlQuery prefix(global.db); - prefix.prepare("Delete from filter where lid not in (select lid from SearchIndex where weight>=:weight and content like :word) and lid not in (select data from DataStore where key=:key and lid in (select lid from SearchIndex where weight>:weight2 and content like :word2))"); + prefix.prepare( + "Delete from filter where lid not in (select lid from SearchIndex where weight>=:weight and content " + "like :word) and lid not in (select data from DataStore where key=:key and lid in (select lid " + "from SearchIndex where weight>:weight2 and content like :word2))"); prefix.bindValue(":weight", global.getMinimumRecognitionWeight()); prefix.bindValue(":weight2", global.getMinimumRecognitionWeight()); @@ -885,76 +1002,73 @@ void FilterEngine::filterSearchStringAll(QStringList list) { prefix.bindValue(":word2", string); prefix.bindValue(":key", RESOURCE_NOTE_LID); prefix.exec(); - } - else { // Filter not found. Use FTS search + } else { + // Filter not found. Use FTS search (full text search) + QLOG_TRACE() << "Using FTS search"; if (string.startsWith("-")) { - string = string.remove(0,1).trimmed(); + string = string.remove(0, 1).trimmed(); if (!string.endsWith("*")) - string = string +QString("*"); + string = string + QString("*"); if (string.contains(" ")) - string = "\""+string+"\""; + string = "\"" + string + "\""; sqlnegative.bindValue(":key", RESOURCE_NOTE_LID); sqlnegative.bindValue(":word", string); sqlnegative.bindValue(":word2", string); sqlnegative.exec(); } else { if (!string.endsWith("*")) - string = string +QString("*"); + string = string + QString("*"); if (string.contains(" ")) - string = "\""+string+"\""; + string = "\"" + string + "\""; sql.bindValue(":key", RESOURCE_NOTE_LID); sql.bindValue(":word", string); sql.bindValue(":word2", string); sql.exec(); - } + + + // update relevance by +1 where search term is found in title + NSqlQuery relUpdtSql(global.db); + setupTitleSelectionQuery(relUpdtSql, origString, 1, true); + relUpdtSql.exec(); + + // update relevance by +1 where search term is found as tag value + setupTagSelectionQuery(relUpdtSql, origString, 1, true); + relUpdtSql.exec(); + + relUpdtSql.finish(); } } - sql.finish(); -} + // after we are finished, check for "important" notes (marked by tag important*) + // update relevance by +1 where search term is found as tag value + // here we give boost +3 + setupTagSelectionQuery(sql, QString("important"), 3, true); + sql.exec(); + sql.finish(); +} // filter based upon the title string the user specified. This is for the "all" // filter and not the "any". -void FilterEngine::filterSearchStringIntitleAll(QString string) { +void FilterEngine::filterSearchStringIntitleAll(QString searchStr) { QLOG_TRACE_IN(); - if (!string.startsWith("-")) { - string.remove(0,8); - if (string == "") - string = "*"; - // Filter out the records - NSqlQuery tagSql(global.db); - string = string.replace("*", "%"); - if (!string.endsWith("%")) - string = string +QString("%"); - if (!string.startsWith("%")) - string = QString("%") + string; - tagSql.prepare("Delete from filter where lid not in (select lid from datastore where key=:key and data like :title)"); - tagSql.bindValue(":key", NOTE_TITLE); - tagSql.bindValue(":title", string); - tagSql.exec(); - tagSql.finish(); + NSqlQuery sql(global.db); + if (!searchStr.startsWith("-")) { + // in" title + searchStr.remove(0, 8); // remove 8 chars of "intitle:" + setupTitleSelectionQuery(sql, searchStr, 0, false); } else { - string.remove(0,9); - if (string == "") - string = "*"; - // Filter out the records - NSqlQuery tagSql(global.db); - string = string.replace("*", "%"); - if (not string.contains("%")) - string = QString("%") +string +QString("%"); - tagSql.prepare("Delete from filter where lid in (select lid from datastore where key=:key and data like :data)"); - tagSql.bindValue(":key", NOTE_TITLE); - tagSql.bindValue(":data", string); - - tagSql.exec(); - tagSql.finish(); + // NOT "in" title + searchStr.remove(0, 9); // remove 9 chars of "!intitle:" + setupTitleSelectionQuery(sql, searchStr, 0, true); } + sql.exec(); + sql.finish(); } @@ -1288,46 +1402,33 @@ void FilterEngine::filterSearchStringResourceRecognitionTypeAll(QString string) } + + // filter based upon the tag string the user specified. This is for the "all" // filter and not the "any". void FilterEngine::filterSearchStringTagAll(QString string) { QLOG_TRACE_IN(); + NSqlQuery sql(global.db); + if (!string.startsWith("-")) { - string.remove(0,4); + // positive search + string.remove(0, 4); if (string == "") string = "*"; - // Filter out the records - NSqlQuery tagSql(global.db); - if (not string.contains("*")) - tagSql.prepare("Delete from filter where lid not in (select lid from datastore where key=:notetagkey and data in (select lid from DataStore where data=:tagname and key=:tagnamekey))"); - else { - tagSql.prepare("Delete from filter where lid not in (select lid from datastore where key=:notetagkey and data in (select lid from DataStore where data like :tagname and key=:tagnamekey))"); - string = string.replace("*", "%"); - } - tagSql.bindValue(":tagname", string); - tagSql.bindValue(":tagnamekey", TAG_NAME); - tagSql.bindValue(":notetagkey", NOTE_TAG_LID); - tagSql.exec(); - tagSql.finish(); + // Filter out the records + setupTagSelectionQuery(sql, string, 0, false); } else { - string.remove(0,5); + // negative search + string.remove(0, 5); if (string == "") string = "*"; + // Filter out the records - NSqlQuery tagSql(global.db); - if (not string.contains("*")) - tagSql.prepare("Delete from filter where lid in (select lid from datastore where key=:notetagkey and data in (select lid from DataStore where data=:tagname and key=:tagnamekey))"); - else { - tagSql.prepare("Delete from filter where lid in (select lid from datastore where key=:notetagkey and data in (select lid from DataStore where data like :tagname and key=:tagnamekey))"); - string = string.replace("*", "%"); - } - tagSql.bindValue(":tagname", string); - tagSql.bindValue(":tagnamekey", TAG_NAME); - tagSql.bindValue(":notetagkey", NOTE_TAG_LID); - tagSql.exec(); - tagSql.finish(); + setupTagSelectionQuery(sql, string, 0, true); } + sql.exec(); + sql.finish(); } diff --git a/filters/filterengine.h b/filters/filterengine.h index 8272b556..c94cd23c 100644 --- a/filters/filterengine.h +++ b/filters/filterengine.h @@ -46,7 +46,7 @@ class FilterEngine : public QObject void filterSearchStringReminderTimeAll(QString string); void filterSearchStringReminderTimeAny(QString string); void filterSearchStringTagAll(QString string); - void filterSearchStringIntitleAll(QString string); + void filterSearchStringIntitleAll(QString searchStr); void filterSearchStringResourceAll(QString string); void filterSearchStringCoordinatesAll(QString string, int key); void filterSearchStringAuthorAll(QString string); diff --git a/global.h b/global.h index c4430e93..26b5985d 100644 --- a/global.h +++ b/global.h @@ -75,9 +75,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #define NOTE_TABLE_REMINDER_TIME_DONE_POSITION 22 #define NOTE_TABLE_PINNED_POSITION 23 #define NOTE_TABLE_COLOR_POSITION 24 + +// generated thumbnail of the note #define NOTE_TABLE_THUMBNAIL_POSITION 25 -#define NOTE_TABLE_COLUMN_COUNT 26 +// internal column used for relevance search; value is generated during search +#define NOTE_TABLE_SEARCH_RELEVANCE_POSITION 26 + + +// count of columns in the table (=> must be last column no. plus 1) +#define NOTE_TABLE_COLUMN_COUNT 27 #define MOUSE_MIDDLE_CLICK_NEW_TAB 0 diff --git a/gui/ntableview.cpp b/gui/ntableview.cpp index 69638388..195ae388 100644 --- a/gui/ntableview.cpp +++ b/gui/ntableview.cpp @@ -72,20 +72,27 @@ NTableView::NTableView(QWidget *parent) : QLOG_TRACE() << "Initializing proxy"; this->proxy = new NoteSortFilterProxyModel(); proxy->setSourceModel(model()); - global.settings->beginGroup("SaveState"); - Qt::SortOrder order = Qt::SortOrder(global.settings->value("sortOrder", 0).toInt()); - int col = global.settings->value("sortColumn", NOTE_TABLE_DATE_CREATED_POSITION).toInt(); - global.settings->endGroup(); - this->setSortingEnabled(true); - proxy->setFilterKeyColumn(NOTE_TABLE_LID_POSITION); - sortByColumn(col, order); - noteModel->sort(col,order); + + // TODO experimental: disable sorting on view table level + // global.settings->beginGroup("SaveState"); + // Qt::SortOrder order = Qt::SortOrder(global.settings->value("sortOrder", 0).toInt()); + // int col = global.settings->value("sortColumn", NOTE_TABLE_DATE_CREATED_POSITION).toInt(); + // global.settings->endGroup(); + // + // this->setSortingEnabled(true); + // proxy->setFilterKeyColumn(NOTE_TABLE_LID_POSITION); + // sortByColumn(col, order); + // noteModel->sort(col,order); + + //refreshData(); setModel(proxy); + // disable user sorting + this->setSortingEnabled(false); - // Set the date deligates - QLOG_TRACE() << "Setting up table deligates"; + // Set the date delegates + QLOG_TRACE() << "Setting up table delegates"; dateDelegate = new DateDelegate(); blankNumber = new NumberDelegate(NumberDelegate::BlankNumber); kbNumber = new NumberDelegate(NumberDelegate::KBNumber); @@ -108,6 +115,7 @@ NTableView::NTableView(QWidget *parent) : this->setItemDelegateForColumn(NOTE_TABLE_PINNED_POSITION, trueFalseDelegate); this->setItemDelegateForColumn(NOTE_TABLE_REMINDER_ORDER_POSITION, reminderOrderDelegate); this->setItemDelegateForColumn(NOTE_TABLE_THUMBNAIL_POSITION, thumbnailDelegate); + this->setItemDelegateForColumn(NOTE_TABLE_SEARCH_RELEVANCE_POSITION, blankNumber); QLOG_TRACE() << "Setting up column headers"; global.settings->beginGroup("Debugging"); @@ -158,6 +166,8 @@ NTableView::NTableView(QWidget *parent) : tableViewHeader->sizeAction->setChecked(true); if (!isColumnHidden(NOTE_TABLE_THUMBNAIL_POSITION)) tableViewHeader->thumbnailAction->setChecked(true); + if (!isColumnHidden(NOTE_TABLE_SEARCH_RELEVANCE_POSITION)) + tableViewHeader->relevanceAction->setChecked(true); if (!isColumnHidden(NOTE_TABLE_TAGS_POSITION)) tableViewHeader->tagsAction->setChecked(true); if (!isColumnHidden(NOTE_TABLE_REMINDER_TIME_POSITION)) @@ -194,6 +204,7 @@ NTableView::NTableView(QWidget *parent) : this->model()->setHeaderData(NOTE_TABLE_IS_DIRTY_POSITION, Qt::Horizontal, QObject::tr("Sync")); this->model()->setHeaderData(NOTE_TABLE_SIZE_POSITION, Qt::Horizontal, QObject::tr("Size")); this->model()->setHeaderData(NOTE_TABLE_THUMBNAIL_POSITION, Qt::Horizontal, QObject::tr("Thumbnail")); + this->model()->setHeaderData(NOTE_TABLE_SEARCH_RELEVANCE_POSITION, Qt::Horizontal, QObject::tr("Relevance")); this->model()->setHeaderData(NOTE_TABLE_PINNED_POSITION, Qt::Horizontal, QObject::tr("Pinned")); contextMenu = new QMenu(this); @@ -326,7 +337,7 @@ NTableView::NTableView(QWidget *parent) : colorMenu->addAction(noteTitleColorMagentaAction); connect(noteTitleColorMagentaAction, SIGNAL(triggered()), this, SLOT(setTitleColorMagenta())); - repositionColumns(); + repositionColumns(); resizeColumns(); setColumnsVisible(); if (!isColumnHidden(NOTE_TABLE_THUMBNAIL_POSITION) && global.listView == Global::ListViewWide) @@ -480,11 +491,13 @@ void NTableView::refreshData() { while(model()->canFetchMore()) model()->fetchMore(); - // resort the table. I'm not sure why, but it doesn't always - // do this itself. - Qt::SortOrder so = this->tableViewHeader->sortIndicatorOrder(); - int si = this->tableViewHeader->sortIndicatorSection(); - this->sortByColumn(si, so); + + // TODO experimental: disable sorting on view table level + // // resort the table. I'm not sure why, but it doesn't always + // // do this itself. + // Qt::SortOrder so = this->tableViewHeader->sortIndicatorOrder(); + // int si = this->tableViewHeader->sortIndicatorSection(); + // this->sortByColumn(si, so); // Re-select any notes refreshSelection(); @@ -1028,6 +1041,9 @@ void NTableView::saveColumnsVisible() { value = isColumnHidden(NOTE_TABLE_THUMBNAIL_POSITION); global.settings->setValue("thumbnail", value); + value = isColumnHidden(NOTE_TABLE_SEARCH_RELEVANCE_POSITION); + global.settings->setValue("relevance", value); + value = isColumnHidden(NOTE_TABLE_SOURCE_APPLICATION_POSITION); global.settings->setValue("sourceApplication", value); @@ -1135,6 +1151,10 @@ void NTableView::setColumnsVisible() { tableViewHeader->thumbnailAction->setChecked(!value); setColumnHidden(NOTE_TABLE_THUMBNAIL_POSITION, value); + value = global.settings->value("relevance", true).toBool(); + tableViewHeader->relevanceAction->setChecked(!value); + setColumnHidden(NOTE_TABLE_SEARCH_RELEVANCE_POSITION, value); + value = global.settings->value("reminderTime", false).toBool(); tableViewHeader->reminderTimeAction->setChecked(!value); setColumnHidden(NOTE_TABLE_REMINDER_TIME_POSITION, value); @@ -1222,6 +1242,10 @@ void NTableView::repositionColumns() { to = global.getColumnPosition("noteTableThumbnailPosition"); if (to>=0) horizontalHeader()->moveSection(from, to); + from = horizontalHeader()->visualIndex(NOTE_TABLE_SEARCH_RELEVANCE_POSITION); + to = global.getColumnPosition("noteTableRelevancePosition"); + if (to>=0) horizontalHeader()->moveSection(from, to); + from = horizontalHeader()->visualIndex(NOTE_TABLE_SOURCE_APPLICATION_POSITION); to = global.getColumnPosition("noteTableSourceApplicationPosition"); if (to>=0) horizontalHeader()->moveSection(from, to); @@ -1261,50 +1285,76 @@ void NTableView::repositionColumns() { void NTableView::resizeColumns() { int width = global.getColumnWidth("noteTableAltitudePosition"); if (width>0) setColumnWidth(NOTE_TABLE_ALTITUDE_POSITION, width); + width = global.getColumnWidth("noteTableAuthorPosition"); if (width>0) setColumnWidth(NOTE_TABLE_AUTHOR_POSITION, width); + width = global.getColumnWidth("noteTableDateCreatedPosition"); if (width>0) setColumnWidth(NOTE_TABLE_DATE_CREATED_POSITION, width); + width = global.getColumnWidth("noteTableDateDeletedPosition"); if (width>0) setColumnWidth(NOTE_TABLE_DATE_DELETED_POSITION, width); + width = global.getColumnWidth("noteTableDateSubjectPosition"); if (width>0) setColumnWidth(NOTE_TABLE_DATE_SUBJECT_POSITION, width); + width = global.getColumnWidth("noteTableDateUpdatedPosition"); if (width>0) setColumnWidth(NOTE_TABLE_DATE_UPDATED_POSITION, width); + width = global.getColumnWidth("noteTableHasEncryptionPosition"); if (width>0) setColumnWidth(NOTE_TABLE_HAS_ENCRYPTION_POSITION, width); + width = global.getColumnWidth("noteTableTodoPosition"); if (width>0) setColumnWidth(NOTE_TABLE_HAS_TODO_POSITION, width); + width = global.getColumnWidth("noteTableIsDirtyPosition"); if (width>0) setColumnWidth(NOTE_TABLE_IS_DIRTY_POSITION, width); + width = global.getColumnWidth("noteTableLatitudePosition"); if (width>0) setColumnWidth(NOTE_TABLE_LATITUDE_POSITION, width); + width = global.getColumnWidth("noteTableLidPosition"); if (width>0) setColumnWidth(NOTE_TABLE_LID_POSITION, width); + width = global.getColumnWidth("noteTableLongitudePosition"); if (width>0) setColumnWidth(NOTE_TABLE_LONGITUDE_POSITION, width); + width = global.getColumnWidth("noteTableNotebookLidPosition"); if (width>0) setColumnWidth(NOTE_TABLE_NOTEBOOK_LID_POSITION, width); + width = global.getColumnWidth("noteTableNotebookPosition"); if (width>0) setColumnWidth(NOTE_TABLE_NOTEBOOK_POSITION, width); + width = global.getColumnWidth("noteTableSizePosition"); if (width>0) setColumnWidth(NOTE_TABLE_SIZE_POSITION, width); + width = global.getColumnWidth("noteTableSourceApplicationPosition"); if (width>0) setColumnWidth(NOTE_TABLE_SOURCE_APPLICATION_POSITION, width); + width = global.getColumnWidth("noteTableSourcePosition"); if (width>0) setColumnWidth(NOTE_TABLE_SOURCE_POSITION, width); + width = global.getColumnWidth("noteTableSourceUrlPosition"); if (width>0) setColumnWidth(NOTE_TABLE_SOURCE_URL_POSITION, width); + width = global.getColumnWidth("noteTableTagsPosition"); if (width>0) setColumnWidth(NOTE_TABLE_TAGS_POSITION, width); + width = global.getColumnWidth("noteTableTitlePosition"); if (width>0) setColumnWidth(NOTE_TABLE_TITLE_POSITION, width); + width = global.getColumnWidth("noteTableThumbnailPosition"); if (width>0) setColumnWidth(NOTE_TABLE_THUMBNAIL_POSITION, width); + + width = global.getColumnWidth("noteTableRelevancePosition"); + if (width>0) setColumnWidth(NOTE_TABLE_SEARCH_RELEVANCE_POSITION, width); + width = global.getColumnWidth("noteTableReminderTimePosition"); if (width>0) setColumnWidth(NOTE_TABLE_REMINDER_TIME_POSITION, width); + width = global.getColumnWidth("noteTableReminderTimeDonePosition"); if (width>0) setColumnWidth(NOTE_TABLE_REMINDER_TIME_DONE_POSITION, width); + width = global.getColumnWidth("noteTableReminderOrderPosition"); if (width>0) setColumnWidth(NOTE_TABLE_REMINDER_ORDER_POSITION, width); } diff --git a/gui/ntableview.h b/gui/ntableview.h index 10b1594a..66f71373 100644 --- a/gui/ntableview.h +++ b/gui/ntableview.h @@ -41,6 +41,8 @@ class NTableView : public QTableView //unsigned int filterPosition; DateDelegate *dateDelegate; NumberDelegate *blankNumber; + + // size kb/Mb.. NumberDelegate *kbNumber; TrueFalseDelegate *trueFalseDelegate; ImageDelegate *thumbnailDelegate; diff --git a/gui/ntableviewheader.cpp b/gui/ntableviewheader.cpp index 4845a759..98e3abf7 100644 --- a/gui/ntableviewheader.cpp +++ b/gui/ntableviewheader.cpp @@ -27,8 +27,7 @@ extern Global global; //* things like custom context menus //************************************************************ NTableViewHeader::NTableViewHeader(Qt::Orientation orientation, QWidget *parent) : - QHeaderView(orientation, parent) -{ + QHeaderView(orientation, parent) { #if QT_VERSION < 0x050000 setClickable(true); @@ -144,39 +143,46 @@ NTableViewHeader::NTableViewHeader(Qt::Orientation orientation, QWidget *parent) thumbnailAction->setCheckable(true); addAction(thumbnailAction); + relevanceAction = new QAction(this); + relevanceAction->setText(tr("Relevance")); + relevanceAction->setCheckable(true); + addAction(relevanceAction); + this->setMouseTracking(true); - connect(this, SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(saveSort(int, Qt::SortOrder))); - - connect(createdDateAction, SIGNAL(toggled(bool)), this, SLOT(createdDateChecked(bool))); - connect(titleAction, SIGNAL(toggled(bool)), this, SLOT(titleChecked(bool))); - connect(changedDateAction, SIGNAL(toggled(bool)), this, SLOT(changedDateChecked(bool))); - connect(subjectDateAction, SIGNAL(toggled(bool)), this, SLOT(subjectDateChecked(bool))); - connect(notebookAction, SIGNAL(toggled(bool)), this, SLOT(notebookChecked(bool))); - connect(tagsAction, SIGNAL(toggled(bool)), this, SLOT(tagsChecked(bool))); - connect(urlAction, SIGNAL(toggled(bool)), this, SLOT(urlChecked(bool))); - connect(authorAction, SIGNAL(toggled(bool)), this, SLOT(authorChecked(bool))); - connect(hasTodoAction, SIGNAL(toggled(bool)), this, SLOT(hasTodoChecked(bool))); - connect(hasEncryptionAction, SIGNAL(toggled(bool)), this, SLOT(hasEncryptionChecked(bool))); - connect(sizeAction, SIGNAL(toggled(bool)), this, SLOT(sizeChecked(bool))); - connect(thumbnailAction, SIGNAL(toggled(bool)), this, SLOT(thumbnailChecked(bool))); - connect(latitudeAction, SIGNAL(toggled(bool)), this, SLOT(latitudeChecked(bool))); - connect(longitudeAction, SIGNAL(toggled(bool)), this, SLOT(longitudeChecked(bool))); - connect(altitudeAction, SIGNAL(toggled(bool)), this, SLOT(altitudeChecked(bool))); - connect(synchronizedAction, SIGNAL(toggled(bool)), this, SLOT(synchronizedChecked(bool))); - connect(sourceAction, SIGNAL(toggled(bool)), this, SLOT(sourceChecked(bool))); - connect(reminderTimeAction, SIGNAL(toggled(bool)), this, SLOT(reminderTimeChecked(bool))); - connect(reminderTimeDoneAction, SIGNAL(toggled(bool)), this, SLOT(reminderTimeDoneChecked(bool))); - connect(reminderOrderAction, SIGNAL(toggled(bool)), this, SLOT(reminderOrderChecked(bool))); - connect(pinnedAction, SIGNAL(toggled(bool)), this, SLOT(pinnedChecked(bool))); + connect(this, SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)), this, SLOT(saveSort(int, Qt::SortOrder))); + + connect(createdDateAction, SIGNAL(toggled(bool)), this, SLOT(createdDateChecked(bool))); + connect(titleAction, SIGNAL(toggled(bool)), this, SLOT(titleChecked(bool))); + connect(changedDateAction, SIGNAL(toggled(bool)), this, SLOT(changedDateChecked(bool))); + connect(subjectDateAction, SIGNAL(toggled(bool)), this, SLOT(subjectDateChecked(bool))); + connect(notebookAction, SIGNAL(toggled(bool)), this, SLOT(notebookChecked(bool))); + connect(tagsAction, SIGNAL(toggled(bool)), this, SLOT(tagsChecked(bool))); + connect(urlAction, SIGNAL(toggled(bool)), this, SLOT(urlChecked(bool))); + connect(authorAction, SIGNAL(toggled(bool)), this, SLOT(authorChecked(bool))); + connect(hasTodoAction, SIGNAL(toggled(bool)), this, SLOT(hasTodoChecked(bool))); + connect(hasEncryptionAction, SIGNAL(toggled(bool)), this, SLOT(hasEncryptionChecked(bool))); + connect(sizeAction, SIGNAL(toggled(bool)), this, SLOT(sizeChecked(bool))); + connect(thumbnailAction, SIGNAL(toggled(bool)), this, SLOT(thumbnailChecked(bool))); + connect(relevanceAction, SIGNAL(toggled(bool)), this, SLOT(relevanceChecked(bool))); + connect(latitudeAction, SIGNAL(toggled(bool)), this, SLOT(latitudeChecked(bool))); + connect(longitudeAction, SIGNAL(toggled(bool)), this, SLOT(longitudeChecked(bool))); + connect(altitudeAction, SIGNAL(toggled(bool)), this, SLOT(altitudeChecked(bool))); + connect(synchronizedAction, SIGNAL(toggled(bool)), this, SLOT(synchronizedChecked(bool))); + connect(sourceAction, SIGNAL(toggled(bool)), this, SLOT(sourceChecked(bool))); + connect(reminderTimeAction, SIGNAL(toggled(bool)), this, SLOT(reminderTimeChecked(bool))); + connect(reminderTimeDoneAction, SIGNAL(toggled(bool)), this, SLOT(reminderTimeDoneChecked(bool))); + connect(reminderOrderAction, SIGNAL(toggled(bool)), this, SLOT(reminderOrderChecked(bool))); + connect(pinnedAction, SIGNAL(toggled(bool)), this, SLOT(pinnedChecked(bool))); this->setFont(global.getGuiFont(font())); - QString css = global.getThemeCss("noteTableViewHeaderCss"); - if (css!="") - this->setStyleSheet(css); + QString css = global.getThemeCss("noteTableViewHeaderCss"); + if (css != "") + this->setStyleSheet(css); + this->setDefaultAlignment(Qt::AlignLeft); } @@ -284,6 +290,10 @@ void NTableViewHeader::thumbnailChecked(bool checked) { emit (setColumnVisible(NOTE_TABLE_THUMBNAIL_POSITION, checked)); checkActions(); } +void NTableViewHeader::relevanceChecked(bool checked) { + emit (setColumnVisible(NOTE_TABLE_SEARCH_RELEVANCE_POSITION, checked)); + checkActions(); +} void NTableViewHeader::reminderTimeChecked(bool checked) { emit (setColumnVisible(NOTE_TABLE_REMINDER_TIME_POSITION, checked)); checkActions(); @@ -305,3 +315,7 @@ void NTableViewHeader::pinnedChecked(bool checked) { bool NTableViewHeader::isThumbnailVisible() { return thumbnailAction->isChecked(); } + +bool NTableViewHeader::isRelevanceVisible() { + return relevanceAction->isChecked(); +} diff --git a/gui/ntableviewheader.h b/gui/ntableviewheader.h index e80bfd14..bc98a338 100644 --- a/gui/ntableviewheader.h +++ b/gui/ntableviewheader.h @@ -48,12 +48,14 @@ class NTableViewHeader : public QHeaderView QAction *hasEncryptionAction; QAction *sizeAction; QAction *thumbnailAction; + QAction *relevanceAction; QAction *reminderTimeAction; QAction *reminderOrderAction; QAction *reminderTimeDoneAction; QAction *pinnedAction; void checkActions(); bool isThumbnailVisible(); + bool isRelevanceVisible(); signals: @@ -80,6 +82,7 @@ public slots: void hasEncryptionChecked(bool); void sizeChecked(bool); void thumbnailChecked(bool); + void relevanceChecked(bool); void reminderTimeChecked(bool); void reminderTimeDoneChecked(bool); void reminderOrderChecked(bool); diff --git a/models/notemodel.cpp b/models/notemodel.cpp index 8311eb26..5ec2f280 100644 --- a/models/notemodel.cpp +++ b/models/notemodel.cpp @@ -38,90 +38,114 @@ extern Global global; // Generic constructor NoteModel::NoteModel(QObject *parent) - :QSqlTableModel(parent, global.db->conn) -{ + : QSqlTableModel(parent, global.db->conn) { // Check if the table exists. If not, create it. NSqlQuery sql(global.db); - sql.exec("Select * from sqlite_master where type='table' and name='NoteTable';"); + + sql.exec("Select * from sqlite_master where type='table' and name='NoteTable';"); if (!sql.next()) - this->createTable(); + this->createNoteTable(); + + sql.exec("Select * from sqlite_master where type='view' and name='NoteTableV';"); + if (!sql.next()) + this->createNoteTableV(); + sql.finish(); this->setEditStrategy(QSqlTableModel::OnFieldChange); - this->setTable("NoteTable"); + this->setTable("NoteTableV"); this->setFilter("lid in (select lid from filter)"); } +QString NoteModel::orderByClause() const +{ + return "order by relevance desc, isDirty desc, dateUpdated desc"; +} + + // Destructor NoteModel::~NoteModel() { } + + //* Create the NoteModel table. -void NoteModel::createTable() { +void NoteModel::createNoteTable() { QLOG_TRACE() << "Entering NoteModel::createTable()"; QLOG_DEBUG() << "Creating table NoteTable"; NSqlQuery sql(global.db); - QString command("Create table if not exists NoteTable (" + - QString("lid integer primary key,") + - QString("dateCreated real default null,") + - QString("dateUpdated real default null,") + - QString("title text default null collate nocase,") + - QString("notebookLid integer default null,") + - QString("notebook text default null collate nocase,") + - QString("tags text default null collate nocase,") + - - QString("author text default null collate nocase,") + - QString("dateSubject real default null,") + - QString("dateDeleted real default null,") + - - QString("source text default null collate nocase,") + - QString("sourceUrl text default null collate nocase,") + - QString("sourceApplication text default null collate nocase,") + - QString("latitude real default null,") + - QString("longitude real default null,") + - QString("altitude real default null,") + - QString("hasEncryption integer default null,") + - QString("hasTodo integer default null,") + - QString("isDirty integer default null,") + - QString("size integer default null,") + - QString("reminderOrder real default null,") + - QString("reminderTime real default null,") + - QString("reminderDoneTime real default null,") + - QString("isPinned integer default null,") + - QString("titleColor text default null,") + - QString("thumbnail default null") + - QString(")")); + QString command( + "Create table if not exists NoteTable (" + "lid integer primary key," + "dateCreated real default null," + "dateUpdated real default null," + "title text default null collate nocase," + "notebookLid integer default null," + "notebook text default null collate nocase," + "tags text default null collate nocase," + "author text default null collate nocase," + "dateSubject real default null," + "dateDeleted real default null," + "source text default null collate nocase," + "sourceUrl text default null collate nocase," + "sourceApplication text default null collate nocase," + "latitude real default null," + "longitude real default null," + "altitude real default null," + "hasEncryption integer default null," + "hasTodo integer default null," + "isDirty integer default null," + "size integer default null," + "reminderOrder real default null," + "reminderTime real default null," + "reminderDoneTime real default null," + "isPinned integer default null," + "titleColor text default null," + "thumbnail default null" + ")"); if (!sql.exec(command) || - !sql.exec("CREATE INDEX if not exists NoteTable_Title_Index on NoteTable (title)") || - !sql.exec("CREATE INDEX if not exists NoteTable_Author_Index on NoteTable (author)") || - !sql.exec("CREATE INDEX if not exists NoteTable_Notebook_Index on NoteTable (notebook)") || - !sql.exec("CREATE INDEX if not exists NoteTable_Notebook_Lid_Index on NoteTable (notebookLid)") || - !sql.exec("CREATE INDEX if not exists NoteTable_DateCreated_Index on NoteTable (dateCreated)") || - !sql.exec("CREATE INDEX if not exists NoteTable_DateUpdated_Index on NoteTable (dateUpdated)") || - !sql.exec("CREATE INDEX if not exists NoteTable_Date_Subject_Index on NoteTable (dateSubject)") || - !sql.exec("CREATE INDEX if not exists NoteTable_Date_Deleted_Index on NoteTable (dateDeleted)") || - !sql.exec("CREATE INDEX if not exists NoteTable_Source_Index on NoteTable (source)") || - !sql.exec("CREATE INDEX if not exists NoteTable_Source_Url_Index on NoteTable (sourceUrl)") || - !sql.exec("CREATE INDEX if not exists NoteTable_Source_Application_Index on NoteTable (sourceApplication)") || - !sql.exec("CREATE INDEX if not exists NoteTable_Latitude_Index on NoteTable (latitude)") || - !sql.exec("CREATE INDEX if not exists NoteTable_Longitude_Index on NoteTable (longitude)") || - !sql.exec("CREATE INDEX if not exists NoteTable_Altitude_Index on NoteTable (altitude)") || - !sql.exec("CREATE INDEX if not exists NoteTable_Has_Encryption_Index on NoteTable (hasEncryption)") || - !sql.exec("CREATE INDEX if not exists NoteTable_Has_Todo_Index on NoteTable (hasTodo)") || - !sql.exec("CREATE INDEX if not exists NoteTable_Is_Dirty_Index on NoteTable (isDirty)") || - !sql.exec("CREATE INDEX if not exists NoteTable_Reminder_Order_Index on NoteTable (reminderOrder)") || - !sql.exec("CREATE INDEX if not exists NoteTable_Reminder_Time_Index on NoteTable (reminderTime)") || - !sql.exec("CREATE INDEX if not exists NoteTable_isPinned_Index on NoteTable (isPinned)") || - !sql.exec("CREATE INDEX if not exists NoteTable_Reminder_Done_Time_Index on NoteTable (reminderDoneTime)") - ) { + !sql.exec("CREATE INDEX if not exists NoteTable_Title_Index on NoteTable (title)") || + !sql.exec("CREATE INDEX if not exists NoteTable_Author_Index on NoteTable (author)") || + !sql.exec("CREATE INDEX if not exists NoteTable_Notebook_Index on NoteTable (notebook)") || + !sql.exec("CREATE INDEX if not exists NoteTable_Notebook_Lid_Index on NoteTable (notebookLid)") || + !sql.exec("CREATE INDEX if not exists NoteTable_DateCreated_Index on NoteTable (dateCreated)") || + !sql.exec("CREATE INDEX if not exists NoteTable_DateUpdated_Index on NoteTable (dateUpdated)") || + !sql.exec("CREATE INDEX if not exists NoteTable_Date_Subject_Index on NoteTable (dateSubject)") || + !sql.exec("CREATE INDEX if not exists NoteTable_Date_Deleted_Index on NoteTable (dateDeleted)") || + !sql.exec("CREATE INDEX if not exists NoteTable_Source_Index on NoteTable (source)") || + !sql.exec("CREATE INDEX if not exists NoteTable_Source_Url_Index on NoteTable (sourceUrl)") || + !sql.exec("CREATE INDEX if not exists NoteTable_Source_Application_Index on NoteTable (sourceApplication)") || + !sql.exec("CREATE INDEX if not exists NoteTable_Latitude_Index on NoteTable (latitude)") || + !sql.exec("CREATE INDEX if not exists NoteTable_Longitude_Index on NoteTable (longitude)") || + !sql.exec("CREATE INDEX if not exists NoteTable_Altitude_Index on NoteTable (altitude)") || + !sql.exec("CREATE INDEX if not exists NoteTable_Has_Encryption_Index on NoteTable (hasEncryption)") || + !sql.exec("CREATE INDEX if not exists NoteTable_Has_Todo_Index on NoteTable (hasTodo)") || + !sql.exec("CREATE INDEX if not exists NoteTable_Is_Dirty_Index on NoteTable (isDirty)") || + !sql.exec("CREATE INDEX if not exists NoteTable_Reminder_Order_Index on NoteTable (reminderOrder)") || + !sql.exec("CREATE INDEX if not exists NoteTable_Reminder_Time_Index on NoteTable (reminderTime)") || + !sql.exec("CREATE INDEX if not exists NoteTable_isPinned_Index on NoteTable (isPinned)") || + !sql.exec("CREATE INDEX if not exists NoteTable_Reminder_Done_Time_Index on NoteTable (reminderDoneTime)") + ) { QLOG_ERROR() << "Creation of NoteTable table failed: " << sql.lastError(); } sql.finish(); } +//* Create the NoteModel table. +void NoteModel::createNoteTableV() { + QLOG_DEBUG() << "Creating table NoteTableV"; + NSqlQuery sql(global.db); + sql.exec("create view NoteTableV as select lid,dateCreated,dateUpdated,title,notebookLid,notebook,tags,author," + "dateSubject,dateDeleted,source,sourceUrl,sourceApplication,latitude,longitude,altitude," + "hasEncryption,hasTodo,isDirty,size,reminderOrder,reminderTime,reminderDoneTime," + "isPinned,titleColor,thumbnail,(select f.relevance from filter f where f.lid=n.lid) as relevance " + "from NoteTable n"); + sql.finish(); +} + //int NoteModel::rowCount(const QModelIndex & /*parent*/) const // { // QLOG_TRACE() << "Entering NoteModel::rowCount()"; @@ -172,3 +196,9 @@ QVariant NoteModel::data (const QModelIndex & index, int role) const { } return QSqlTableModel::data(index,role); } + +bool NoteModel::select() { + //QLOG_DEBUG() << "Performing NoteModel select " << selectStatement(); + return QSqlTableModel::select(); +} + diff --git a/models/notemodel.h b/models/notemodel.h index 9fefe82e..e3a38ad2 100644 --- a/models/notemodel.h +++ b/models/notemodel.h @@ -32,9 +32,16 @@ class NoteModel : public QSqlTableModel ~NoteModel(); //int rowCount(const QModelIndex &parent) const; int columnCount(const QModelIndex &parent) const; - void createTable(); + + // NoteTable - data table with note data + void createNoteTable(); + // NoteTableV - view based on NoteTable used to get "relevance" column from "filter" table + void createNoteTableV(); + Qt::ItemFlags flags(const QModelIndex &index) const; QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const; + bool select(); + QString orderByClause() const; signals: diff --git a/sql/databaseconnection.cpp b/sql/databaseconnection.cpp index a9fc9453..c0aa723b 100644 --- a/sql/databaseconnection.cpp +++ b/sql/databaseconnection.cpp @@ -82,11 +82,16 @@ DatabaseConnection::DatabaseConnection(QString connection) } - QLOG_TRACE() << "Creating filter table"; - tempTable.exec("Create table if not exists filter (lid integer)"); - tempTable.exec("delete from filter"); + QLOG_TRACE() << "Re-creating filter table"; + tempTable.exec("drop table if exists filter"); + tempTable.exec("create table filter (lid integer, relevance integer)"); + // index could be useful as we do joins on table display + // may also slow down search + // so maybe reevaluate this + tempTable.exec("create index Filter_Lid_Index on filter (lid)"); + QLOG_TRACE() << "Adding to filter table"; - tempTable.exec("insert into filter select distinct lid from NoteTable;"); + tempTable.exec("insert into filter (lid,relevance) select distinct lid,0 from NoteTable"); QLOG_TRACE() << "Addition complete"; tempTable.finish(); @@ -94,8 +99,7 @@ DatabaseConnection::DatabaseConnection(QString connection) } -// Destructor. Close the database & delete the -// memory used by the valiables. +// Destructor. Close the database & delete the memory used by the variables. DatabaseConnection::~DatabaseConnection() { conn.close(); delete configStore; diff --git a/threads/syncrunner.cpp b/threads/syncrunner.cpp index 9a53edef..9c6e60af 100644 --- a/threads/syncrunner.cpp +++ b/threads/syncrunner.cpp @@ -190,7 +190,7 @@ void SyncRunner::evernoteSync() { tagTable.cleanupMissingParents(); if (!error) - emit setMessage(tr("Sync Complete Successfully"), defaultMsgTimeout); + emit setMessage(tr("Sync completed successfully"), defaultMsgTimeout); QLOG_TRACE() << "Leaving SyncRunner::evernoteSync()"; } diff --git a/translations/nixnote2_ca.ts b/translations/nixnote2_ca.ts index 81133ac0..1acb4290 100644 --- a/translations/nixnote2_ca.ts +++ b/translations/nixnote2_ca.ts @@ -4698,7 +4698,7 @@ any key or using the right or middle mouse buttons. - Sync Complete Successfully + Sync completed successfully diff --git a/translations/nixnote2_cs_CZ.ts b/translations/nixnote2_cs_CZ.ts index c4a885d5..37ee3064 100644 --- a/translations/nixnote2_cs_CZ.ts +++ b/translations/nixnote2_cs_CZ.ts @@ -4799,7 +4799,7 @@ nebo ukončete snímkování libovolnou klávesou či prostředním tlačítekm - Sync Complete Successfully + Sync completed successfully Synchronizace úspěšně dokončena diff --git a/translations/nixnote2_da.ts b/translations/nixnote2_da.ts index 24b85999..c497dc74 100644 --- a/translations/nixnote2_da.ts +++ b/translations/nixnote2_da.ts @@ -4698,7 +4698,7 @@ any key or using the right or middle mouse buttons. - Sync Complete Successfully + Sync completed successfully diff --git a/translations/nixnote2_de.ts b/translations/nixnote2_de.ts index c44ae818..94b10660 100644 --- a/translations/nixnote2_de.ts +++ b/translations/nixnote2_de.ts @@ -4742,7 +4742,7 @@ oder drücke eine Taste oder verwende die rechte oder mittlere Maustaste, um die - Sync Complete Successfully + Sync completed successfully diff --git a/translations/nixnote2_es.ts b/translations/nixnote2_es.ts index fbbfa481..bd7823b8 100644 --- a/translations/nixnote2_es.ts +++ b/translations/nixnote2_es.ts @@ -4698,7 +4698,7 @@ any key or using the right or middle mouse buttons. - Sync Complete Successfully + Sync completed successfully diff --git a/translations/nixnote2_fr.ts b/translations/nixnote2_fr.ts index ede8e7f7..dba0f1cb 100644 --- a/translations/nixnote2_fr.ts +++ b/translations/nixnote2_fr.ts @@ -4751,7 +4751,7 @@ en appuyant sur n'importe quelle touche. - Sync Complete Successfully + Sync completed successfully Synchronisation complétée avec succès diff --git a/translations/nixnote2_ja.ts b/translations/nixnote2_ja.ts index f20344db..03d7e9c4 100644 --- a/translations/nixnote2_ja.ts +++ b/translations/nixnote2_ja.ts @@ -4743,7 +4743,7 @@ any key or using the right or middle mouse buttons. - Sync Complete Successfully + Sync completed successfully diff --git a/translations/nixnote2_pl.ts b/translations/nixnote2_pl.ts index 85fa8179..29e4aad5 100644 --- a/translations/nixnote2_pl.ts +++ b/translations/nixnote2_pl.ts @@ -4698,7 +4698,7 @@ any key or using the right or middle mouse buttons. - Sync Complete Successfully + Sync completed successfully diff --git a/translations/nixnote2_pt.ts b/translations/nixnote2_pt.ts index 219cadc1..eeca0567 100644 --- a/translations/nixnote2_pt.ts +++ b/translations/nixnote2_pt.ts @@ -4698,7 +4698,7 @@ any key or using the right or middle mouse buttons. - Sync Complete Successfully + Sync completed successfully diff --git a/translations/nixnote2_ru.ts b/translations/nixnote2_ru.ts index 8f910e43..aad970e5 100644 --- a/translations/nixnote2_ru.ts +++ b/translations/nixnote2_ru.ts @@ -4709,7 +4709,7 @@ any key or using the right or middle mouse buttons. - Sync Complete Successfully + Sync completed successfully diff --git a/translations/nixnote2_sk.ts b/translations/nixnote2_sk.ts index 6fb2fc91..83a23f91 100644 --- a/translations/nixnote2_sk.ts +++ b/translations/nixnote2_sk.ts @@ -4698,7 +4698,7 @@ any key or using the right or middle mouse buttons. - Sync Complete Successfully + Sync completed successfully diff --git a/translations/nixnote2_zh_CN.ts b/translations/nixnote2_zh_CN.ts index d5fe5f9a..3aa9f8f4 100644 --- a/translations/nixnote2_zh_CN.ts +++ b/translations/nixnote2_zh_CN.ts @@ -4786,7 +4786,7 @@ any key or using the right or middle mouse buttons. - Sync Complete Successfully + Sync completed successfully 同步完成(成功) diff --git a/translations/nixnote2_zh_TW.ts b/translations/nixnote2_zh_TW.ts index d13142a0..3646ba6b 100644 --- a/translations/nixnote2_zh_TW.ts +++ b/translations/nixnote2_zh_TW.ts @@ -4747,7 +4747,7 @@ any key or using the right or middle mouse buttons. - Sync Complete Successfully + Sync completed successfully