From bdb01c2c068df326f5a8328ed1492ab1bea388c5 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Wed, 20 Jan 2016 19:07:07 +0100 Subject: Renamed Akonadi2 to Sink (except for documentation). --- akonadish/CMakeLists.txt | 29 ---- akonadish/TODO | 11 -- akonadish/akonadish_utils.cpp | 134 ----------------- akonadish/akonadish_utils.h | 88 ----------- akonadish/main.cpp | 115 --------------- akonadish/repl/repl.cpp | 91 ------------ akonadish/repl/repl.h | 35 ----- akonadish/repl/replStates.cpp | 171 --------------------- akonadish/repl/replStates.h | 87 ----------- akonadish/state.cpp | 144 ------------------ akonadish/state.h | 52 ------- akonadish/syntax_modules/akonadi_clear.cpp | 61 -------- akonadish/syntax_modules/akonadi_count.cpp | 83 ----------- akonadish/syntax_modules/akonadi_create.cpp | 118 --------------- akonadish/syntax_modules/akonadi_list.cpp | 114 -------------- akonadish/syntax_modules/akonadi_modify.cpp | 120 --------------- akonadish/syntax_modules/akonadi_remove.cpp | 110 -------------- akonadish/syntax_modules/akonadi_stat.cpp | 120 --------------- akonadish/syntax_modules/akonadi_sync.cpp | 67 --------- akonadish/syntax_modules/core_syntax.cpp | 204 ------------------------- akonadish/syntaxtree.cpp | 221 ---------------------------- akonadish/syntaxtree.h | 80 ---------- akonadish/utils.cpp | 42 ------ akonadish/utils.h | 30 ---- 24 files changed, 2327 deletions(-) delete mode 100644 akonadish/CMakeLists.txt delete mode 100644 akonadish/TODO delete mode 100644 akonadish/akonadish_utils.cpp delete mode 100644 akonadish/akonadish_utils.h delete mode 100644 akonadish/main.cpp delete mode 100644 akonadish/repl/repl.cpp delete mode 100644 akonadish/repl/repl.h delete mode 100644 akonadish/repl/replStates.cpp delete mode 100644 akonadish/repl/replStates.h delete mode 100644 akonadish/state.cpp delete mode 100644 akonadish/state.h delete mode 100644 akonadish/syntax_modules/akonadi_clear.cpp delete mode 100644 akonadish/syntax_modules/akonadi_count.cpp delete mode 100644 akonadish/syntax_modules/akonadi_create.cpp delete mode 100644 akonadish/syntax_modules/akonadi_list.cpp delete mode 100644 akonadish/syntax_modules/akonadi_modify.cpp delete mode 100644 akonadish/syntax_modules/akonadi_remove.cpp delete mode 100644 akonadish/syntax_modules/akonadi_stat.cpp delete mode 100644 akonadish/syntax_modules/akonadi_sync.cpp delete mode 100644 akonadish/syntax_modules/core_syntax.cpp delete mode 100644 akonadish/syntaxtree.cpp delete mode 100644 akonadish/syntaxtree.h delete mode 100644 akonadish/utils.cpp delete mode 100644 akonadish/utils.h (limited to 'akonadish') diff --git a/akonadish/CMakeLists.txt b/akonadish/CMakeLists.txt deleted file mode 100644 index eaedf9a..0000000 --- a/akonadish/CMakeLists.txt +++ /dev/null @@ -1,29 +0,0 @@ -project(akonadish) - -find_package(Readline REQUIRED) - - -set(akonadi2_cli_SRCS - main.cpp - syntaxtree.cpp - syntax_modules/core_syntax.cpp - syntax_modules/akonadi_list.cpp - syntax_modules/akonadi_clear.cpp - syntax_modules/akonadi_count.cpp - syntax_modules/akonadi_create.cpp - syntax_modules/akonadi_modify.cpp - syntax_modules/akonadi_remove.cpp - syntax_modules/akonadi_stat.cpp - syntax_modules/akonadi_sync.cpp - akonadish_utils.cpp - repl/repl.cpp - repl/replStates.cpp - state.cpp - utils.cpp) - -include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) - -add_executable(${PROJECT_NAME} ${akonadi2_cli_SRCS}) -target_link_libraries(${PROJECT_NAME} Qt5::Core ${Readline_LIBRARY} akonadi2common) -install(TARGETS ${PROJECT_NAME} ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) - diff --git a/akonadish/TODO b/akonadish/TODO deleted file mode 100644 index 93c4ff1..0000000 --- a/akonadish/TODO +++ /dev/null @@ -1,11 +0,0 @@ -* commands - * improve modify/remove/create to dynamically add syntax items for each type - * improve modify/remove/create to autocomplete resource names -* provide a setting to turn on/off user interaction during commands (e.g. deletion confirmations) - * add a "ask the user a question" helper in State - * confirm deletions in remove -* handle env vars and similar for scripting purposes -* key/value syntax objects -* json objects! (set json on; ...) -* make the shell generic and have it load a plugin matching the name of argv[0] for syntax - diff --git a/akonadish/akonadish_utils.cpp b/akonadish/akonadish_utils.cpp deleted file mode 100644 index 27a863d..0000000 --- a/akonadish/akonadish_utils.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2015 Aaron Seigo - * Copyright (C) 2015 Christian Mollekopf - * - * 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 2 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, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "akonadish_utils.h" - -#include "common/clientapi.h" - -#include "utils.h" - -namespace AkonadishUtils -{ - -static QStringList s_types = QStringList() << "resource" << "folder" << "mail" << "event"; - -bool isValidStoreType(const QString &type) -{ - return s_types.contains(type); -} - -StoreBase &getStore(const QString &type) -{ - if (type == "folder") { - static Store store; - return store; - } else if (type == "mail") { - static Store store; - return store; - } else if (type == "event") { - static Store store; - return store; - } else if (type == "resource") { - static Store store; - return store; - } - - //TODO: reinstate the warning+assert - //Q_ASSERT(false); - //qWarning() << "Trying to get a store that doesn't exist, falling back to event"; - static Store store; - return store; -} - -QSharedPointer loadModel(const QString &type, Akonadi2::Query query) -{ - if (type == "folder") { - query.requestedProperties << "name" << "parent"; - } else if (type == "mail") { - query.requestedProperties << "subject" << "folder" << "date"; - } else if (type == "event") { - query.requestedProperties << "summary"; - } else if (type == "resource") { - query.requestedProperties << "type"; - } - auto model = getStore(type).loadModel(query); - Q_ASSERT(model); - return model; -} - -QStringList resourceIds(State &state) -{ - QStringList resources; - Akonadi2::Query query; - query.liveQuery = false; - auto model = AkonadishUtils::loadModel("resource", query); - - QObject::connect(model.data(), &QAbstractItemModel::rowsInserted, [model, &resources] (const QModelIndex &index, int start, int end) mutable { - for (int i = start; i <= end; i++) { - auto object = model->data(model->index(i, 0, index), Akonadi2::Store::DomainObjectBaseRole).value(); - resources << object->identifier(); - } - }); - - QObject::connect(model.data(), &QAbstractItemModel::dataChanged, [model, state](const QModelIndex &, const QModelIndex &, const QVector &roles) { - if (roles.contains(Akonadi2::Store::ChildrenFetchedRole)) { - state.commandFinished(); - } - }); - - state.commandStarted(); - - return resources; -} - -QStringList resourceCompleter(const QStringList &, const QString &fragment, State &state) -{ - return Utils::filteredCompletions(resourceIds(state), fragment); -} - -QStringList resourceOrTypeCompleter(const QStringList &commands, const QString &fragment, State &state) -{ - static QStringList types = QStringList() << "resource" << "folder" << "mail" << "event"; - if (commands.count() == 1) { - return Utils::filteredCompletions(s_types, fragment); - } - - return Utils::filteredCompletions(resourceIds(state), fragment); -} - -QStringList typeCompleter(const QStringList &commands, const QString &fragment, State &state) -{ - return Utils::filteredCompletions(s_types, fragment); -} - -QMap keyValueMapFromArgs(const QStringList &args) -{ - //TODO: this is not the most clever of algorithms. preserved during the port of commands - // from akonadi2_client ... we can probably do better, however ;) - QMap map; - for (int i = 0; i + 2 <= args.size(); i += 2) { - map.insert(args.at(i), args.at(i + 1)); - } - - return map; -} - -} - diff --git a/akonadish/akonadish_utils.h b/akonadish/akonadish_utils.h deleted file mode 100644 index 5dd24f1..0000000 --- a/akonadish/akonadish_utils.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2015 Aaron Seigo - * Copyright (C) 2015 Christian Mollekopf - * - * 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 2 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, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#pragma once - -#include -#include - -#include "common/query.h" -#include "common/clientapi.h" - -#include "state.h" - -namespace AkonadishUtils -{ - -class StoreBase; - -bool isValidStoreType(const QString &type); -StoreBase &getStore(const QString &type); -QSharedPointer loadModel(const QString &type, Akonadi2::Query query); -QStringList resourceIds(); -QStringList resourceCompleter(const QStringList &, const QString &fragment, State &state); -QStringList resourceOrTypeCompleter(const QStringList &commands, const QString &fragment, State &state); -QStringList typeCompleter(const QStringList &commands, const QString &fragment, State &state); -QMap keyValueMapFromArgs(const QStringList &args); - -/** - * A small abstraction layer to use the akonadi store with the type available as string. - */ -class StoreBase { -public: - virtual Akonadi2::ApplicationDomain::ApplicationDomainType::Ptr getObject() = 0; - virtual Akonadi2::ApplicationDomain::ApplicationDomainType::Ptr getObject(const QByteArray &resourceInstanceIdentifier, const QByteArray &identifier = QByteArray()) = 0; - virtual KAsync::Job create(const Akonadi2::ApplicationDomain::ApplicationDomainType &type) = 0; - virtual KAsync::Job modify(const Akonadi2::ApplicationDomain::ApplicationDomainType &type) = 0; - virtual KAsync::Job remove(const Akonadi2::ApplicationDomain::ApplicationDomainType &type) = 0; - virtual QSharedPointer loadModel(const Akonadi2::Query &query) = 0; -}; - -template -class Store : public StoreBase { -public: - Akonadi2::ApplicationDomain::ApplicationDomainType::Ptr getObject() Q_DECL_OVERRIDE { - return T::Ptr::create(); - } - - Akonadi2::ApplicationDomain::ApplicationDomainType::Ptr getObject(const QByteArray &resourceInstanceIdentifier, const QByteArray &identifier = QByteArray()) Q_DECL_OVERRIDE { - return T::Ptr::create(resourceInstanceIdentifier, identifier, 0, QSharedPointer::create()); - } - - KAsync::Job create(const Akonadi2::ApplicationDomain::ApplicationDomainType &type) Q_DECL_OVERRIDE { - return Akonadi2::Store::create(*static_cast(&type)); - } - - KAsync::Job modify(const Akonadi2::ApplicationDomain::ApplicationDomainType &type) Q_DECL_OVERRIDE { - return Akonadi2::Store::modify(*static_cast(&type)); - } - - KAsync::Job remove(const Akonadi2::ApplicationDomain::ApplicationDomainType &type) Q_DECL_OVERRIDE { - return Akonadi2::Store::remove(*static_cast(&type)); - } - - QSharedPointer loadModel(const Akonadi2::Query &query) Q_DECL_OVERRIDE { - return Akonadi2::Store::loadModel(query); - } -}; - - -} - diff --git a/akonadish/main.cpp b/akonadish/main.cpp deleted file mode 100644 index 4c00b9b..0000000 --- a/akonadish/main.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2014 Aaron Seigo - * - * 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 2 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, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include - -#include -#include -#include -#include - -#include "syntaxtree.h" -// #include "jsonlistener.h" -#include "repl/repl.h" - -/* - * modes of operation: - * - * 1. called with no commands: start the REPL - * 2. called with -: listen for commands on stdin - * 3. called with a filename: try to run it as a script - * 4. called with commands: try to match to syntax and run the result - */ - -int enterRepl() -{ - if (State::hasEventLoop()) { - return 0; - } - - Repl *repl = new Repl; - QObject::connect(repl, &QStateMachine::finished, - repl, &QObject::deleteLater); - QObject::connect(repl, &QStateMachine::finished, - QCoreApplication::instance(), &QCoreApplication::quit); - - State::setHasEventLoop(true); - int rv = QCoreApplication::instance()->exec(); - State::setHasEventLoop(false); - return rv; -} - -bool goInteractive(const QStringList &, State &) -{ - enterRepl(); - return true; -} - -Syntax::List goInteractiveSyntax() -{ - Syntax interactive("go_interactive", QString(), &goInteractive); - return Syntax::List() << interactive; -} - -void processCommandStream(QTextStream &stream) -{ - SyntaxTree::self()->registerSyntax(&goInteractiveSyntax); - QString line = stream.readLine(); - while (!line.isEmpty()) { - line = line.trimmed(); - - if (!line.isEmpty() && !line.startsWith('#')) { - SyntaxTree::self()->run(SyntaxTree::tokenize(line)); - } - - line = stream.readLine(); - } -} - -int main(int argc, char *argv[]) -{ - const bool interactive = isatty(fileno(stdin)); - const bool startRepl = (argc == 1) && interactive; - //TODO: make a json command parse cause that would be awesomesauce - const bool fromScript = !startRepl && QFile::exists(argv[1]); - - //qDebug() << "state at startup is" << interactive << startRepl << fromScript; - - QCoreApplication app(argc, argv); - app.setApplicationName(fromScript ? "interactive-app-shell" : argv[0]); - - if (startRepl) { - return enterRepl(); - } else if (fromScript) { - QFile f(argv[1]); - if (!f.open(QIODevice::ReadOnly)) { - return 1; - } - - QTextStream inputStream(&f); - processCommandStream(inputStream); - } else if (!interactive) { - QTextStream inputStream(stdin); - processCommandStream(inputStream); - } else { - QStringList commands = app.arguments(); - commands.removeFirst(); - return SyntaxTree::self()->run(commands); - } -} diff --git a/akonadish/repl/repl.cpp b/akonadish/repl/repl.cpp deleted file mode 100644 index 499a4af..0000000 --- a/akonadish/repl/repl.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2014 Aaron Seigo - * - * 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 2 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, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "repl.h" - -#include - -#include -#include -#include -#include -#include - -#include "replStates.h" -#include "syntaxtree.h" - -Repl::Repl(QObject *parent) - : QStateMachine(parent) -{ - // readline history setup - using_history(); - read_history(commandHistoryPath().toLocal8Bit()); - - // create all states - ReadState *read = new ReadState(this); - UnfinishedReadState *unfinishedRead = new UnfinishedReadState(this); - EvalState *eval = new EvalState(this); - PrintState *print = new PrintState(this); - QFinalState *final = new QFinalState(this); - - // connect the transitions - read->addTransition(read, SIGNAL(command(QString)), eval); - read->addTransition(read, SIGNAL(exitRequested()), final); - - unfinishedRead->addTransition(unfinishedRead, SIGNAL(command(QString)), eval); - unfinishedRead->addTransition(unfinishedRead, SIGNAL(exitRequested()), final); - - eval->addTransition(eval, SIGNAL(completed()), read); - eval->addTransition(eval, SIGNAL(continueInput()), unfinishedRead); - eval->addTransition(eval, SIGNAL(output(QString)), print); - - print->addTransition(print, SIGNAL(completed()), eval); - - setInitialState(read); - printWelcomeBanner(); - start(); -} - -Repl::~Repl() -{ - // readline history writing - write_history(commandHistoryPath().toLocal8Bit()); -} - -void Repl::printWelcomeBanner() -{ - QTextStream out(stdout); - out << QObject::tr("Welcome to the Akonadi2 interative shell!\n"); - out << QObject::tr("Type `help` for information on the available commands.\n"); - out.flush(); -} - -QString Repl::commandHistoryPath() -{ - const QString path = QStandardPaths::writableLocation(QStandardPaths::DataLocation); - - if (!QFile::exists(path)) { - QDir dir; - dir.mkpath(path); - } - - return path + "/repl_history"; -} - -#include "moc_repl.cpp" diff --git a/akonadish/repl/repl.h b/akonadish/repl/repl.h deleted file mode 100644 index d8d2533..0000000 --- a/akonadish/repl/repl.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2014 Aaron Seigo - * - * 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 2 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, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#pragma once - -#include - -class Repl : public QStateMachine -{ - Q_OBJECT - -public: - Repl(QObject *parent = 0); - ~Repl(); - -private: - static void printWelcomeBanner(); - static QString commandHistoryPath(); -}; diff --git a/akonadish/repl/replStates.cpp b/akonadish/repl/replStates.cpp deleted file mode 100644 index 55fdf39..0000000 --- a/akonadish/repl/replStates.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) 2014 Aaron Seigo - * - * 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 2 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, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "replStates.h" - -#include -#include - -#include -#include - -#include -#include -#include - -#include "syntaxtree.h" - -static char *akonadi2_cli_next_tab_complete_match(const char *text, int state); -static char ** akonadi2_cli_tab_completion(const char *text, int start, int end); - -ReadState::ReadState(QState *parent) - : QState(parent) -{ - rl_completion_entry_function = akonadi2_cli_next_tab_complete_match; - rl_attempted_completion_function = akonadi2_cli_tab_completion; -} - -void ReadState::onEntry(QEvent *event) -{ - Q_UNUSED(event) - char *line = readline(prompt()); - - if (!line) { - std::cout << std::endl; - emit exitRequested(); - return; - } - - // we have actual data, so let's wait for a full line of text - QByteArray input(line); - const QString text = QString(line).simplified(); - //qDebug() << "Line is ... " << text; - - if (text.length() > 0) { - add_history(line); - } - - free(line); - emit command(text); -} - -const char *ReadState::prompt() const -{ - return "> "; -} - -UnfinishedReadState::UnfinishedReadState(QState *parent) - : ReadState(parent) -{ -} - -const char *UnfinishedReadState::prompt() const -{ - return " "; -} - -EvalState::EvalState(QState *parent) - : QState(parent) -{ -} - -void EvalState::onEntry(QEvent *event) -{ - QStateMachine::SignalEvent *e = dynamic_cast(event); - - const QString command = e ? e->arguments()[0].toString() : QString(); - - if (command.isEmpty()) { - complete(); - return; - } - - if (command.right(1) == "\\") { - m_partial += " " + command.left(command.size() - 1); - continueInput(); - } else { - m_partial += " " + command; - complete(); - } -} - -void EvalState::complete() -{ - m_partial = m_partial.simplified(); - - if (!m_partial.isEmpty()) { - //emit output("Processing ... " + command); - const QStringList commands = SyntaxTree::tokenize(m_partial); - SyntaxTree::self()->run(commands); - m_partial.clear(); - } - - emit completed(); -} - -PrintState::PrintState(QState *parent) - : QState(parent) -{ -} - -void PrintState::onEntry(QEvent *event) -{ - QStateMachine::SignalEvent *e = dynamic_cast(event); - - if (e && !e->arguments().isEmpty()) { - const QString command = e->arguments()[0].toString(); - QTextStream stream(stdout); - stream << command << "\n"; - } - - emit completed(); -} - -static QStringList tab_completion_full_state; -static bool tab_completion_at_root = false; - -static char **akonadi2_cli_tab_completion(const char *text, int start, int end) -{ - tab_completion_at_root = start == 0; - tab_completion_full_state = QString(rl_line_buffer).remove(start, end - start).split(" ", QString::SkipEmptyParts); - return NULL; -} - -static char *akonadi2_cli_next_tab_complete_match(const char *text, int state) -{ - const QString fragment(text); - Syntax::List nearest = SyntaxTree::self()->nearestSyntax(tab_completion_full_state, fragment); - //for (auto syntax: nearest) { qDebug() << "Nearest: " << syntax.keyword; } - - if (nearest.isEmpty()) { - SyntaxTree::Command command = SyntaxTree::self()->match(tab_completion_full_state); - if (command.first && command.first->completer) { - QStringList commandCompletions = command.first->completer(tab_completion_full_state, fragment, SyntaxTree::self()->state()); - if (commandCompletions.size() > state) { - return qstrdup(commandCompletions[state].toUtf8()); - } - } - } else if (nearest.size() > state) { - return qstrdup(nearest[state].keyword.toUtf8()); - } - - return rl_filename_completion_function(text, state); -} - -#include "moc_replStates.cpp" diff --git a/akonadish/repl/replStates.h b/akonadish/repl/replStates.h deleted file mode 100644 index a0d3f90..0000000 --- a/akonadish/repl/replStates.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2014 Aaron Seigo - * - * 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 2 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, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#pragma once - -#include - -class QSocketNotifier; - -class ReadState : public QState -{ - Q_OBJECT - -public: - ReadState(QState *parent = 0); - -Q_SIGNALS: - void command(const QString &command); - void exitRequested(); - -protected: - void onEntry(QEvent *event); - virtual const char *prompt() const; -}; - -class UnfinishedReadState : public ReadState -{ - Q_OBJECT - -public: - UnfinishedReadState(QState *parent = 0); - -protected: - const char *prompt() const; -}; - -class EvalState : public QState -{ - Q_OBJECT - -public: - EvalState(QState *parent = 0); - -Q_SIGNALS: - void completed(); - void continueInput(); - void output(const QString &output); - -protected: - void onEntry(QEvent *event); - -private: - void complete(); - - QString m_partial; -}; - -class PrintState : public QState -{ - Q_OBJECT - -public: - PrintState(QState *parent = 0); - -Q_SIGNALS: - void completed(); - -protected: - void onEntry(QEvent *event); -}; - diff --git a/akonadish/state.cpp b/akonadish/state.cpp deleted file mode 100644 index 9fb5bcc..0000000 --- a/akonadish/state.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2014 Aaron Seigo - * - * 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 2 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, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "state.h" - -#include -#include -#include -#include - -#include "common/log.h" - -static bool s_hasEventLoop = false; - -class State::Private -{ -public: - Private() - : outStream(stdout) - { - } - - QEventLoop *eventLoop() - { - if (!event) { - event = new QEventLoop; - } - - return event; - } - - int debugLevel = 0; - QEventLoop *event = 0; - bool timing = false; - QTextStream outStream; -}; - -State::State() - : d(new Private) -{ -} - -void State::print(const QString &message, unsigned int indentationLevel) const -{ - for (unsigned int i = 0; i < indentationLevel; ++i) { - d->outStream << "\t"; - } - - d->outStream << message; -} - -void State::printLine(const QString &message, unsigned int indentationLevel) const -{ - print(message, indentationLevel); - d->outStream << "\n"; - d->outStream.flush(); -} - -void State::printError(const QString &errorMessage, const QString &errorCode) const -{ - printLine("ERROR" + (errorCode.isEmpty() ? "" : " " + errorCode) + ": " + errorMessage); -} - -void State::setDebugLevel(unsigned int level) -{ - if (level < 7) { - d->debugLevel = level; - } -} - -unsigned int State::debugLevel() const -{ - return d->debugLevel; -} - -int State::commandStarted() const -{ - if (!s_hasEventLoop) { - return QCoreApplication::exec(); - } else if (!d->eventLoop()->isRunning()) { - return d->eventLoop()->exec(); - } - - return 0; -} - -void State::commandFinished(int returnCode) const -{ - if (!s_hasEventLoop) { - QCoreApplication::exit(returnCode); - } else { - d->eventLoop()->exit(returnCode); - } -} - -void State::setHasEventLoop(bool evented) -{ - s_hasEventLoop = evented; -} - -bool State::hasEventLoop() -{ - return s_hasEventLoop; -} - -void State::setCommandTiming(bool time) -{ - d->timing = time; -} - -bool State::commandTiming() const -{ - return d->timing; -} - -void State::setLoggingLevel(const QString &level) const -{ - Akonadi2::Log::setDebugOutputLevel(Akonadi2::Log::debugLevelFromName(level.toLatin1())); -} - -QString State::loggingLevel() const -{ - // do not turn this into a single line return: that core dumps due to allocation of - // the byte array in Akonadi2::Log - QByteArray rv = Akonadi2::Log::debugLevelName(Akonadi2::Log::debugOutputLevel()); - return rv.toLower(); -} - diff --git a/akonadish/state.h b/akonadish/state.h deleted file mode 100644 index 3c4c2c7..0000000 --- a/akonadish/state.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2014 Aaron Seigo - * - * 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 2 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, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#pragma once - -#include - -class State -{ -public: - State(); - - void print(const QString &message, unsigned int indentationLevel = 0) const; - void printLine(const QString &message = QString(), unsigned int indentationLevel = 0) const; - void printError(const QString &errorMessage, const QString &errorCode = QString()) const; - - void setDebugLevel(unsigned int level); - unsigned int debugLevel() const; - - void setCommandTiming(bool); - bool commandTiming() const; - - int commandStarted() const; - void commandFinished(int returnCode = 0) const; - - void setLoggingLevel(const QString &level) const; - QString loggingLevel() const; - - static void setHasEventLoop(bool evented); - static bool hasEventLoop(); - -private: - class Private; - Private * const d; -}; - diff --git a/akonadish/syntax_modules/akonadi_clear.cpp b/akonadish/syntax_modules/akonadi_clear.cpp deleted file mode 100644 index d328849..0000000 --- a/akonadish/syntax_modules/akonadi_clear.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2014 Aaron Seigo - * - * 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 2 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, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include // tr() -#include - -#include "common/resource.h" -#include "common/storage.h" -#include "common/domain/event.h" -#include "common/domain/folder.h" -#include "common/resourceconfig.h" -#include "common/log.h" -#include "common/storage.h" -#include "common/definitions.h" - -#include "akonadish_utils.h" -#include "state.h" -#include "syntaxtree.h" - -namespace AkonadiClear -{ - -bool clear(const QStringList &args, State &state) -{ - for (const auto &resource : args) { - state.print(QObject::tr("Removing local cache for '%1' ...").arg(resource)); - Akonadi2::Store::removeFromDisk(resource.toLatin1()); - state.printLine(QObject::tr("done")); - } - - return true; -} - -Syntax::List syntax() -{ - Syntax clear("clear", QObject::tr("Clears the local cache of one or more resources (be careful!)"), &AkonadiClear::clear); - clear.completer = &AkonadishUtils::resourceCompleter; - - return Syntax::List() << clear; -} - -REGISTER_SYNTAX(AkonadiClear) - -} diff --git a/akonadish/syntax_modules/akonadi_count.cpp b/akonadish/syntax_modules/akonadi_count.cpp deleted file mode 100644 index bb1cd19..0000000 --- a/akonadish/syntax_modules/akonadi_count.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2014 Aaron Seigo - * - * 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 2 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, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include -#include // tr() -#include -#include - -#include "common/resource.h" -#include "common/storage.h" -#include "common/domain/event.h" -#include "common/domain/folder.h" -#include "common/resourceconfig.h" -#include "common/log.h" -#include "common/storage.h" -#include "common/definitions.h" - -#include "akonadish_utils.h" -#include "state.h" -#include "syntaxtree.h" - -namespace AkonadiCount -{ - -bool count(const QStringList &args, State &state) -{ - auto resources = args; - auto type = !resources.isEmpty() ? resources.takeFirst() : QString(); - - if (!type.isEmpty() && !AkonadishUtils::isValidStoreType(type)) { - state.printError(QObject::tr("Unknown type: %1").arg(type)); - return false; - } - - Akonadi2::Query query; - for (const auto &res : resources) { - query.resources << res.toLatin1(); - } - query.liveQuery = false; - - auto model = AkonadishUtils::loadModel(type, query); - QObject::connect(model.data(), &QAbstractItemModel::dataChanged, [model, state](const QModelIndex &, const QModelIndex &, const QVector &roles) { - if (roles.contains(Akonadi2::Store::ChildrenFetchedRole)) { - state.printLine(QObject::tr("Counted results %1").arg(model->rowCount(QModelIndex()))); - state.commandFinished(); - } - }); - - if (!model->data(QModelIndex(), Akonadi2::Store::ChildrenFetchedRole).toBool()) { - return true; - } - - return true; -} - -Syntax::List syntax() -{ - Syntax count("count", QObject::tr("Returns the number of items of a given type in a resource. Usage: count "), &AkonadiCount::count, Syntax::EventDriven); - count.completer = &AkonadishUtils::typeCompleter; - - return Syntax::List() << count; -} - -REGISTER_SYNTAX(AkonadiCount) - -} diff --git a/akonadish/syntax_modules/akonadi_create.cpp b/akonadish/syntax_modules/akonadi_create.cpp deleted file mode 100644 index 377219a..0000000 --- a/akonadish/syntax_modules/akonadi_create.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2014 Aaron Seigo - * - * 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 2 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, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include -#include // tr() -#include -#include - -#include "common/resource.h" -#include "common/storage.h" -#include "common/domain/event.h" -#include "common/domain/folder.h" -#include "common/resourceconfig.h" -#include "common/log.h" -#include "common/storage.h" -#include "common/definitions.h" - -#include "akonadish_utils.h" -#include "state.h" -#include "syntaxtree.h" - -namespace AkonadiCreate -{ - -bool create(const QStringList &allArgs, State &state) -{ - if (allArgs.isEmpty()) { - state.printError(QObject::tr("A type is required"), "akonadicreate/02"); - return false; - } - - if (allArgs.count() < 2) { - state.printError(QObject::tr("A resource ID is required to create items"), "akonadicreate/03"); - return false; - } - - auto args = allArgs; - auto type = args.takeFirst(); - auto &store = AkonadishUtils::getStore(type); - Akonadi2::ApplicationDomain::ApplicationDomainType::Ptr object; - auto resource = args.takeFirst().toLatin1(); - object = store.getObject(resource); - - auto map = AkonadishUtils::keyValueMapFromArgs(args); - for (auto i = map.begin(); i != map.end(); ++i) { - object->setProperty(i.key().toLatin1(), i.value()); - } - - auto result = store.create(*object).exec(); - result.waitForFinished(); - if (result.errorCode()) { - state.printError(QObject::tr("An error occurred while creating the entity: %1").arg(result.errorMessage()), - "akonaid_create_e" + QString::number(result.errorCode())); - } - - return true; -} - -bool resource(const QStringList &args, State &state) -{ - if (args.isEmpty()) { - state.printError(QObject::tr("A resource can not be created without a type"), "akonadicreate/01"); - return false; - } - - auto &store = AkonadishUtils::getStore("resource"); - - auto resourceType = args.at(0); - Akonadi2::ApplicationDomain::ApplicationDomainType::Ptr object = store.getObject(""); - object->setProperty("type", resourceType); - - auto map = AkonadishUtils::keyValueMapFromArgs(args); - for (auto i = map.begin(); i != map.end(); ++i) { - object->setProperty(i.key().toLatin1(), i.value()); - } - - auto result = store.create(*object).exec(); - result.waitForFinished(); - if (result.errorCode()) { - state.printError(QObject::tr("An error occurred while creating the entity: %1").arg(result.errorMessage()), - "akonaid_create_e" + QString::number(result.errorCode())); - } - - return true; -} - - -Syntax::List syntax() -{ - Syntax::List syntax; - - Syntax create("create", QObject::tr("Create items in a resource"), &AkonadiCreate::create); - create.children << Syntax("resource", QObject::tr("Creates a new resource"), &AkonadiCreate::resource); - - syntax << create; - return syntax; -} - -REGISTER_SYNTAX(AkonadiCreate) - -} diff --git a/akonadish/syntax_modules/akonadi_list.cpp b/akonadish/syntax_modules/akonadi_list.cpp deleted file mode 100644 index 7709d3b..0000000 --- a/akonadish/syntax_modules/akonadi_list.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2014 Aaron Seigo - * - * 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 2 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, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include -#include // tr() -#include -#include - -#include "common/resource.h" -#include "common/storage.h" -#include "common/domain/event.h" -#include "common/domain/folder.h" -#include "common/resourceconfig.h" -#include "common/log.h" -#include "common/storage.h" -#include "common/definitions.h" - -#include "akonadish_utils.h" -#include "state.h" -#include "syntaxtree.h" - -namespace AkonadiList -{ - -bool list(const QStringList &args, State &state) -{ - if (args.isEmpty()) { - state.printError(QObject::tr("Please provide at least one type to list (e.g. resource, ..")); - return false; - } - - auto resources = args; - auto type = !resources.isEmpty() ? resources.takeFirst() : QString(); - - if (!type.isEmpty() && !AkonadishUtils::isValidStoreType(type)) { - state.printError(QObject::tr("Unknown type: %1").arg(type)); - return false; - } - - Akonadi2::Query query; - for (const auto &res : resources) { - query.resources << res.toLatin1(); - } - query.liveQuery = false; - - QTime time; - time.start(); - auto model = AkonadishUtils::loadModel(type, query); - if (state.debugLevel() > 0) { - state.printLine(QObject::tr("Folder type %1").arg(type)); - state.printLine(QObject::tr("Loaded model in %1 ms").arg(time.elapsed())); - } - - //qDebug() << "Listing"; - int colSize = 38; //Necessary to display a complete UUID - state.print(QObject::tr("Resource").leftJustified(colSize, ' ', true) + - QObject::tr("Identifier").leftJustified(colSize, ' ', true)); - for (int i = 0; i < model->columnCount(QModelIndex()); i++) { - state.print(" | " + model->headerData(i, Qt::Horizontal).toString().leftJustified(colSize, ' ', true)); - } - state.printLine(); - - QObject::connect(model.data(), &QAbstractItemModel::rowsInserted, [model, colSize, state](const QModelIndex &index, int start, int end) { - for (int i = start; i <= end; i++) { - auto object = model->data(model->index(i, 0, index), Akonadi2::Store::DomainObjectBaseRole).value(); - state.print(object->resourceInstanceIdentifier().leftJustified(colSize, ' ', true)); - state.print(object->identifier().leftJustified(colSize, ' ', true)); - for (int col = 0; col < model->columnCount(QModelIndex()); col++) { - state.print(" | " + model->data(model->index(i, col, index)).toString().leftJustified(colSize, ' ', true)); - } - state.printLine(); - } - }); - - QObject::connect(model.data(), &QAbstractItemModel::dataChanged, [model, state](const QModelIndex &, const QModelIndex &, const QVector &roles) { - if (roles.contains(Akonadi2::Store::ChildrenFetchedRole)) { - state.commandFinished(); - } - }); - - if (!model->data(QModelIndex(), Akonadi2::Store::ChildrenFetchedRole).toBool()) { - return true; - } - - return false; -} - -Syntax::List syntax() -{ - Syntax list("list", QObject::tr("List all resources, or the contents of one or more resources"), &AkonadiList::list, Syntax::EventDriven); - list.completer = &AkonadishUtils::resourceOrTypeCompleter; - return Syntax::List() << list; -} - -REGISTER_SYNTAX(AkonadiList) - -} diff --git a/akonadish/syntax_modules/akonadi_modify.cpp b/akonadish/syntax_modules/akonadi_modify.cpp deleted file mode 100644 index 76a7f5e..0000000 --- a/akonadish/syntax_modules/akonadi_modify.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2014 Aaron Seigo - * - * 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 2 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, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include -#include // tr() -#include -#include - -#include "common/resource.h" -#include "common/storage.h" -#include "common/domain/event.h" -#include "common/domain/folder.h" -#include "common/resourceconfig.h" -#include "common/log.h" -#include "common/storage.h" -#include "common/definitions.h" - -#include "akonadish_utils.h" -#include "state.h" -#include "syntaxtree.h" - -namespace AkonadiModify -{ - -bool modify(const QStringList &args, State &state) -{ - if (args.isEmpty()) { - state.printError(QObject::tr("A type is required"), "akonadi_modify/02"); - return false; - } - - if (args.count() < 2) { - state.printError(QObject::tr("A resource ID is required to remove items"), "akonadi_modify/03"); - return false; - } - - if (args.count() < 3) { - state.printError(QObject::tr("An object ID is required to remove items"), "akonadi_modify/03"); - return false; - } - - auto type = args[0]; - auto resourceId = args[1]; - auto identifier = args[2]; - - auto &store = AkonadishUtils::getStore(type); - Akonadi2::ApplicationDomain::ApplicationDomainType::Ptr object = store.getObject(resourceId.toUtf8(), identifier.toUtf8()); - - auto map = AkonadishUtils::keyValueMapFromArgs(args); - for (auto i = map.begin(); i != map.end(); ++i) { - object->setProperty(i.key().toLatin1(), i.value()); - } - - auto result = store.modify(*object).exec(); - result.waitForFinished(); - if (result.errorCode()) { - state.printError(QObject::tr("An error occurred while removing %1 from %1: %2").arg(identifier).arg(resourceId).arg(result.errorMessage()), - "akonaid__modify_e" + QString::number(result.errorCode())); - } - - return true; -} - -bool resource(const QStringList &args, State &state) -{ - if (args.isEmpty()) { - state.printError(QObject::tr("A resource can not be modified without an id"), "akonadi_modify/01"); - } - - auto &store = AkonadishUtils::getStore("resource"); - - auto resourceId = args.at(0); - Akonadi2::ApplicationDomain::ApplicationDomainType::Ptr object = store.getObject("", resourceId.toLatin1()); - - auto map = AkonadishUtils::keyValueMapFromArgs(args); - for (auto i = map.begin(); i != map.end(); ++i) { - object->setProperty(i.key().toLatin1(), i.value()); - } - - auto result = store.modify(*object).exec(); - result.waitForFinished(); - if (result.errorCode()) { - state.printError(QObject::tr("An error occurred while modifying the resource %1: %2").arg(resourceId).arg(result.errorMessage()), - "akonaid_modify_e" + QString::number(result.errorCode())); - } - - return true; -} - - -Syntax::List syntax() -{ - Syntax modify("modify", QObject::tr("Modify items in a resource"), &AkonadiModify::modify); - Syntax resource("resource", QObject::tr("Modify a resource"), &AkonadiModify::resource);//, Syntax::EventDriven); - resource.completer = &AkonadishUtils::resourceOrTypeCompleter; - modify.children << resource; - - return Syntax::List() << modify; -} - -REGISTER_SYNTAX(AkonadiModify) - -} diff --git a/akonadish/syntax_modules/akonadi_remove.cpp b/akonadish/syntax_modules/akonadi_remove.cpp deleted file mode 100644 index 9691d78..0000000 --- a/akonadish/syntax_modules/akonadi_remove.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2014 Aaron Seigo - * - * 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 2 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, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include -#include // tr() -#include -#include - -#include "common/resource.h" -#include "common/storage.h" -#include "common/domain/event.h" -#include "common/domain/folder.h" -#include "common/resourceconfig.h" -#include "common/log.h" -#include "common/storage.h" -#include "common/definitions.h" - -#include "akonadish_utils.h" -#include "state.h" -#include "syntaxtree.h" - -namespace AkonadiRemove -{ - -bool remove(const QStringList &args, State &state) -{ - if (args.isEmpty()) { - state.printError(QObject::tr("A type is required"), "akonadi_remove/02"); - return false; - } - - if (args.count() < 2) { - state.printError(QObject::tr("A resource ID is required to remove items"), "akonadi_remove/03"); - return false; - } - - if (args.count() < 3) { - state.printError(QObject::tr("An object ID is required to remove items"), "akonadi_remove/03"); - return false; - } - - auto type = args[0]; - auto resourceId = args[1]; - auto identifier = args[2]; - - auto &store = AkonadishUtils::getStore(type); - Akonadi2::ApplicationDomain::ApplicationDomainType::Ptr object = store.getObject(resourceId.toUtf8(), identifier.toUtf8()); - - auto result = store.remove(*object).exec(); - result.waitForFinished(); - if (result.errorCode()) { - state.printError(QObject::tr("An error occurred while removing %1 from %1: %2").arg(identifier).arg(resourceId).arg(result.errorMessage()), - "akonaid_remove_e" + QString::number(result.errorCode())); - } - - return true; -} - -bool resource(const QStringList &args, State &state) -{ - if (args.isEmpty()) { - state.printError(QObject::tr("A resource can not be removed without an id"), "akonadi_remove/01"); - } - - auto &store = AkonadishUtils::getStore("resource"); - - auto resourceId = args.at(0); - Akonadi2::ApplicationDomain::ApplicationDomainType::Ptr object = store.getObject("", resourceId.toLatin1()); - - auto result = store.remove(*object).exec(); - result.waitForFinished(); - if (result.errorCode()) { - state.printError(QObject::tr("An error occurred while removing the resource %1: %2").arg(resourceId).arg(result.errorMessage()), - "akonaid_remove_e" + QString::number(result.errorCode())); - } - - return true; -} - - -Syntax::List syntax() -{ - Syntax remove("remove", QObject::tr("Remove items in a resource"), &AkonadiRemove::remove); - Syntax resource("resource", QObject::tr("Removes a resource"), &AkonadiRemove::resource);//, Syntax::EventDriven); - resource.completer = &AkonadishUtils::resourceCompleter; - remove.children << resource; - - return Syntax::List() << remove; -} - -REGISTER_SYNTAX(AkonadiRemove) - -} diff --git a/akonadish/syntax_modules/akonadi_stat.cpp b/akonadish/syntax_modules/akonadi_stat.cpp deleted file mode 100644 index d10556f..0000000 --- a/akonadish/syntax_modules/akonadi_stat.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2014 Aaron Seigo - * - * 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 2 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, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include // tr() -#include -#include - -#include "common/resource.h" -#include "common/storage.h" -#include "common/domain/event.h" -#include "common/domain/folder.h" -#include "common/resourceconfig.h" -#include "common/log.h" -#include "common/storage.h" -#include "common/definitions.h" - -#include "akonadish_utils.h" -#include "state.h" -#include "syntaxtree.h" - -namespace AkonadiStat -{ - -void statResources(const QStringList &resources, const State &state) -{ - qint64 total = 0; - for (const auto &resource : resources) { - Akonadi2::Storage storage(Akonadi2::storageLocation(), resource, Akonadi2::Storage::ReadOnly); - auto transaction = storage.createTransaction(Akonadi2::Storage::ReadOnly); - - QList databases = transaction.getDatabaseNames(); - for (const auto &databaseName : databases) { - state.printLine(QObject::tr("Database: %1").arg(QString(databaseName)), 1); - auto db = transaction.openDatabase(databaseName); - qint64 size = db.getSize() / 1024; - state.printLine(QObject::tr("Size [kb]: %1").arg(size), 1); - total += size; - } - int diskUsage = 0; - - QDir dir(Akonadi2::storageLocation()); - for (const auto &folder : dir.entryList(QStringList() << resource + "*")) { - diskUsage += Akonadi2::Storage(Akonadi2::storageLocation(), folder, Akonadi2::Storage::ReadOnly).diskUsage(); - } - auto size = diskUsage / 1024; - state.printLine(QObject::tr("Disk usage [kb]: %1").arg(size), 1); - } - - state.printLine(QObject::tr("Total [kb]: %1").arg(total)); -} - -bool statAllResources(State &state) -{ - Akonadi2::Query query; - query.liveQuery = false; - auto model = AkonadishUtils::loadModel("resource", query); - - //SUUUPER ugly, but can't think of a better way with 2 glasses of wine in me on Christmas day - static QStringList resources; - resources.clear(); - - QObject::connect(model.data(), &QAbstractItemModel::rowsInserted, [model](const QModelIndex &index, int start, int end) mutable { - for (int i = start; i <= end; i++) { - auto object = model->data(model->index(i, 0, index), Akonadi2::Store::DomainObjectBaseRole).value(); - resources << object->identifier(); - } - }); - - QObject::connect(model.data(), &QAbstractItemModel::dataChanged, [model, state](const QModelIndex &, const QModelIndex &, const QVector &roles) { - if (roles.contains(Akonadi2::Store::ChildrenFetchedRole)) { - statResources(resources, state); - state.commandFinished(); - } - }); - - if (!model->data(QModelIndex(), Akonadi2::Store::ChildrenFetchedRole).toBool()) { - return true; - } - - return false; -} - -bool stat(const QStringList &args, State &state) -{ - if (args.isEmpty()) { - return statAllResources(state); - } - - statResources(args, state); - return false; -} - -Syntax::List syntax() -{ - Syntax state("stat", QObject::tr("Shows database usage for the resources requested"), &AkonadiStat::stat, Syntax::EventDriven); - state.completer = &AkonadishUtils::resourceCompleter; - - return Syntax::List() << state; -} - -REGISTER_SYNTAX(AkonadiStat) - -} diff --git a/akonadish/syntax_modules/akonadi_sync.cpp b/akonadish/syntax_modules/akonadi_sync.cpp deleted file mode 100644 index 0c994d0..0000000 --- a/akonadish/syntax_modules/akonadi_sync.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2014 Aaron Seigo - * - * 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 2 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, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include // tr() -#include - -#include "common/resource.h" -#include "common/storage.h" -#include "common/domain/event.h" -#include "common/domain/folder.h" -#include "common/resourceconfig.h" -#include "common/log.h" -#include "common/storage.h" -#include "common/definitions.h" - -#include "akonadish_utils.h" -#include "state.h" -#include "syntaxtree.h" - -namespace AkonadiSync -{ - -bool sync(const QStringList &args, State &state) -{ - Akonadi2::Query query; - for (const auto &res : args) { - query.resources << res.toLatin1(); - } - - QTimer::singleShot(0, [query, state]() { - Akonadi2::Store::synchronize(query).then([state]() { - state.printLine("Synchronization complete!"); - state.commandFinished(); - }).exec(); - }); - - return true; -} - -Syntax::List syntax() -{ - Syntax sync("sync", QObject::tr("Syncronizes all resources that are listed; and empty list triggers a syncronizaton on all resources"), &AkonadiSync::sync, Syntax::EventDriven ); - sync.completer = &AkonadishUtils::resourceCompleter; - - return Syntax::List() << sync; -} - -REGISTER_SYNTAX(AkonadiSync) - -} diff --git a/akonadish/syntax_modules/core_syntax.cpp b/akonadish/syntax_modules/core_syntax.cpp deleted file mode 100644 index ccf96c1..0000000 --- a/akonadish/syntax_modules/core_syntax.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (C) 2014 Aaron Seigo - * - * 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 2 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, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include // tr() -#include -#include - -#include "state.h" -#include "syntaxtree.h" -#include "utils.h" - -namespace CoreSyntax -{ - -bool exit(const QStringList &, State &) -{ - ::exit(0); - return true; -} - -bool showHelp(const QStringList &commands, State &state) -{ - SyntaxTree::Command command = SyntaxTree::self()->match(commands); - if (commands.isEmpty()) { - state.printLine(QObject::tr("Welcome to the Akonadi2 command line tool!")); - state.printLine(QObject::tr("Top-level commands:")); - - QSet sorted; - for (auto syntax: SyntaxTree::self()->syntax()) { - sorted.insert(syntax.keyword); - } - - for (auto keyword: sorted) { - state.printLine(keyword, 1); - } - } else if (const Syntax *syntax = command.first) { - //TODO: get parent! - state.print(QObject::tr("Command `%1`").arg(syntax->keyword)); - - if (!syntax->help.isEmpty()) { - state.print(": " + syntax->help); - } - state.printLine(); - - if (!syntax->children.isEmpty()) { - state.printLine("Sub-commands:", 1); - QSet sorted; - for (auto childSyntax: syntax->children) { - sorted.insert(childSyntax.keyword); - } - - for (auto keyword: sorted) { - state.printLine(keyword, 1); - } - } - } else { - state.printError("Unknown command: " + commands.join(" ")); - } - - return true; -} - -QStringList showHelpCompleter(const QStringList &commands, const QString &fragment, State &) -{ - QStringList items; - - for (auto syntax: SyntaxTree::self()->syntax()) { - if (syntax.keyword != QObject::tr("help") && - (fragment.isEmpty() || syntax.keyword.startsWith(fragment))) { - items << syntax.keyword; - } - } - - qSort(items); - return items; -} - -bool setDebugLevel(const QStringList &commands, State &state) -{ - if (commands.count() != 1) { - state.printError(QObject::tr("Wrong number of arguments; expected 1 got %1").arg(commands.count())); - return false; - } - - bool ok = false; - int level = commands[0].toUInt(&ok); - - if (!ok) { - state.printError(QObject::tr("Expected a number between 0 and 6, got %1").arg(commands[0])); - return false; - } - - state.setDebugLevel(level); - return true; -} - -bool printDebugLevel(const QStringList &, State &state) -{ - state.printLine(QString::number(state.debugLevel())); - return true; -} - -bool printCommandTiming(const QStringList &, State &state) -{ - state.printLine(state.commandTiming() ? QObject::tr("on") : QObject::tr("off")); - return true; -} - -void printSyntaxBranch(State &state, const Syntax::List &list, int depth) -{ - if (list.isEmpty()) { - return; - } - - if (depth > 0) { - state.printLine("\\", depth); - } - - for (auto syntax: list) { - state.print("|-", depth); - state.printLine(syntax.keyword); - printSyntaxBranch(state, syntax.children, depth + 1); - } -} - -bool printSyntaxTree(const QStringList &, State &state) -{ - printSyntaxBranch(state, SyntaxTree::self()->syntax(), 0); - return true; -} - -bool setLoggingLevel(const QStringList &commands, State &state) -{ - if (commands.count() != 1) { - state.printError(QObject::tr("Wrong number of arguments; expected 1 got %1").arg(commands.count())); - return false; - } - - state.setLoggingLevel(commands.at(0)); - return true; -} - -bool printLoggingLevel(const QStringList &commands, State &state) -{ - const QString level = state.loggingLevel(); - state.printLine(level); - return true; -} - -Syntax::List syntax() -{ - Syntax::List syntax; - syntax << Syntax("exit", QObject::tr("Exits the application. Ctrl-d also works!"), &CoreSyntax::exit); - - Syntax help("help", QObject::tr("Print command information: help [command]"), &CoreSyntax::showHelp); - help.completer = &CoreSyntax::showHelpCompleter; - syntax << help; - - syntax << Syntax("syntaxtree", QString(), &printSyntaxTree); - - Syntax set("set", QObject::tr("Sets settings for the session")); - set.children << Syntax("debug", QObject::tr("Set the debug level from 0 to 6"), &CoreSyntax::setDebugLevel); - - Syntax setTiming = Syntax("timing", QObject::tr("Whether or not to print the time commands take to complete")); - setTiming.children << Syntax("on", QString(), [](const QStringList &, State &state) -> bool { state.setCommandTiming(true); return true; }); - setTiming.children << Syntax("off", QString(), [](const QStringList &, State &state) -> bool { state.setCommandTiming(false); return true; }); - set.children << setTiming; - - Syntax logging("logging", QObject::tr("Set the logging level to one of Trace, Log, Warning or Error"), &CoreSyntax::setLoggingLevel); - logging.completer = [](const QStringList &, const QString &fragment, State &state) -> QStringList { return Utils::filteredCompletions(QStringList() << "trace" << "log" << "warning" << "error", fragment, Qt::CaseInsensitive); }; - set.children << logging; - - syntax << set; - - Syntax get("get", QObject::tr("Gets settings for the session")); - get.children << Syntax("debug", QObject::tr("The current debug level from 0 to 6"), &CoreSyntax::printDebugLevel); - get.children << Syntax("timing", QObject::tr("Whether or not to print the time commands take to complete"), &CoreSyntax::printCommandTiming); - get.children << Syntax("logging", QObject::tr("The current logging level"), &CoreSyntax::printLoggingLevel); - syntax << get; - - return syntax; -} - -REGISTER_SYNTAX(CoreSyntax) - -} // namespace CoreSyntax - diff --git a/akonadish/syntaxtree.cpp b/akonadish/syntaxtree.cpp deleted file mode 100644 index 4860582..0000000 --- a/akonadish/syntaxtree.cpp +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (C) 2014 Aaron Seigo - * - * 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 2 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, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "syntaxtree.h" - -#include -#include - -SyntaxTree *SyntaxTree::s_module = 0; - -Syntax::Syntax() -{ -} - -Syntax::Syntax(const QString &k, const QString &helpText, std::function l, Interactivity inter) - : keyword(k), - help(helpText), - interactivity(inter), - lambda(l) -{ -} - -SyntaxTree::SyntaxTree() -{ -} - -int SyntaxTree::registerSyntax(std::function f) -{ - m_syntax += f(); - return m_syntax.size(); -} - -SyntaxTree *SyntaxTree::self() -{ - if (!s_module) { - s_module = new SyntaxTree; - } - - return s_module; -} - -Syntax::List SyntaxTree::syntax() const -{ - return m_syntax; -} - -bool SyntaxTree::run(const QStringList &commands) -{ - bool success = false; - m_timeElapsed.start(); - Command command = match(commands); - if (command.first) { - if (command.first->lambda) { - success = command.first->lambda(command.second, m_state); - if (success && command.first->interactivity == Syntax::EventDriven) { - success = m_state.commandStarted(); - } - } else if (command.first->children.isEmpty()) { - m_state.printError(QObject::tr("Broken command... sorry :("), "st_broken"); - } else { - QStringList keywordList; - for (auto syntax: command.first->children) { - keywordList << syntax.keyword; - } - const QString keywords = keywordList.join(" " ); - m_state.printError(QObject::tr("Command requires additional arguments, one of: %1").arg(keywords)); - } - } else { - m_state.printError(QObject::tr("Unknown command"), "st_unknown"); - } - - if (m_state.commandTiming()) { - m_state.printLine(QObject::tr("Time elapsed: %1").arg(m_timeElapsed.elapsed())); - } - return false; -} - -SyntaxTree::Command SyntaxTree::match(const QStringList &commandLine) const -{ - if (commandLine.isEmpty()) { - return Command(); - } - - QStringListIterator commandLineIt(commandLine); - - QVectorIterator syntaxIt(m_syntax); - const Syntax *lastFullSyntax = 0; - QStringList tailCommands; - while (commandLineIt.hasNext() && syntaxIt.hasNext()) { - const QString word = commandLineIt.next(); - while (syntaxIt.hasNext()) { - const Syntax &syntax = syntaxIt.next(); - if (word == syntax.keyword) { - lastFullSyntax = &syntax; - syntaxIt = syntax.children; - break; - } - } - } - - if (lastFullSyntax) { - while (commandLineIt.hasNext()) { - tailCommands << commandLineIt.next(); - } - - return std::make_pair(lastFullSyntax, tailCommands); - } - - return Command(); -} - -Syntax::List SyntaxTree::nearestSyntax(const QStringList &words, const QString &fragment) const -{ - Syntax::List matches; - - //qDebug() << "words are" << words; - if (words.isEmpty()) { - for (const Syntax &syntax: m_syntax) { - if (syntax.keyword.startsWith(fragment)) { - matches.push_back(syntax); - } - } - } else { - QStringListIterator wordIt(words); - QVectorIterator syntaxIt(m_syntax); - Syntax lastFullSyntax; - - while (wordIt.hasNext()) { - const QString &word = wordIt.next(); - while (syntaxIt.hasNext()) { - const Syntax &syntax = syntaxIt.next(); - if (word == syntax.keyword) { - lastFullSyntax = syntax; - syntaxIt = syntax.children; - break; - } - } - } - - //qDebug() << "exiting with" << lastFullSyntax.keyword << words.last(); - if (lastFullSyntax.keyword == words.last()) { - syntaxIt = lastFullSyntax.children; - while (syntaxIt.hasNext()) { - Syntax syntax = syntaxIt.next(); - if (fragment.isEmpty() || syntax.keyword.startsWith(fragment)) { - matches.push_back(syntax); - } - } - } - } - - return matches; -} - -State &SyntaxTree::state() -{ - return m_state; -} - -QStringList SyntaxTree::tokenize(const QString &text) -{ - //TODO: properly tokenize (e.g. "foo bar" should not become ['"foo', 'bar"']a - static const QVector quoters = QVector() << '"' << '\''; - QStringList tokens; - QString acc; - QChar closer; - for (int i = 0; i < text.size(); ++i) { - const QChar c = text.at(i); - if (c == '\\') { - ++i; - if (i < text.size()) { - acc.append(text.at(i)); - } - } else if (!closer.isNull()) { - if (c == closer) { - acc = acc.trimmed(); - if (!acc.isEmpty()) { - tokens << acc; - } - acc.clear(); - closer = QChar(); - } else { - acc.append(c); - } - } else if (c.isSpace()) { - acc = acc.trimmed(); - if (!acc.isEmpty()) { - tokens << acc; - } - acc.clear(); - } else if (quoters.contains(c)) { - closer = c; - } else { - acc.append(c); - } - } - - acc = acc.trimmed(); - if (!acc.isEmpty()) { - tokens << acc; - } - - return tokens; -} - diff --git a/akonadish/syntaxtree.h b/akonadish/syntaxtree.h deleted file mode 100644 index 468aad3..0000000 --- a/akonadish/syntaxtree.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2014 Aaron Seigo - * - * 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 2 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, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#pragma once - -#include "state.h" - -#include -#include -#include - -#include - -class Syntax -{ -public: - typedef QVector List; - - enum Interactivity { - NotInteractive = 0, - EventDriven - }; - - Syntax(); - Syntax(const QString &keyword, - const QString &helpText = QString(), - std::function lambda = std::function(), - Interactivity interactivity = NotInteractive); - - QString keyword; - QString help; - Interactivity interactivity; - std::function lambda; - std::function completer; - - QVector children; -}; - -class SyntaxTree -{ -public: - typedef std::pair Command; - - static SyntaxTree *self(); - - int registerSyntax(std::function f); - Syntax::List syntax() const; - Command match(const QStringList &commands) const; - Syntax::List nearestSyntax(const QStringList &words, const QString &fragment) const; - State &state(); - bool run(const QStringList &commands); - - static QStringList tokenize(const QString &text); - -private: - SyntaxTree(); - - Syntax::List m_syntax; - State m_state; - QTime m_timeElapsed; - static SyntaxTree *s_module; -}; - -#define REGISTER_SYNTAX(name) static const int theTrickFor##name = SyntaxTree::self()->registerSyntax(&name::syntax); diff --git a/akonadish/utils.cpp b/akonadish/utils.cpp deleted file mode 100644 index d2a28ed..0000000 --- a/akonadish/utils.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2016 Aaron Seigo - * - * 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 2 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, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "utils.h" - -namespace Utils -{ - -QStringList filteredCompletions(const QStringList &possibleCompletions, const QString &commandFragment, Qt::CaseSensitivity cs) -{ - if (commandFragment.isEmpty()) { - return possibleCompletions; - } - - QStringList filtered; - for (auto item: possibleCompletions) { - if (item.startsWith(commandFragment, cs)) { - filtered << item; - } - } - - return filtered; -} - -} // namespace Utils - diff --git a/akonadish/utils.h b/akonadish/utils.h deleted file mode 100644 index 82be8d5..0000000 --- a/akonadish/utils.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2016 Aaron Seigo - * - * 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 2 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, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#pragma once - -#include - -namespace Utils -{ - -QStringList filteredCompletions(const QStringList &possibleCompletions, const QString &commandFragment, Qt::CaseSensitivity cs = Qt::CaseSensitive); - -} // namespace Utils - -- cgit v1.2.3