diff --git a/querying/CMakeLists.txt b/querying/CMakeLists.txt
index 67a860a34ba7e4c3de4872a6b40c56d8bd81f01f..80325d48cbe97ea68d150be8f11ebe1a573cfe52 100644
--- a/querying/CMakeLists.txt
+++ b/querying/CMakeLists.txt
@@ -1,12 +1,46 @@
-cmake_minimum_required(VERSION 3.15)
-project(Querying)
+cmake_minimum_required(VERSION 3.0)
 
 set(CMAKE_CXX_STANDARD 17)
 
-set(CMAKE_CXX_FLAGS "-g -Wall -pedantic -Wextra")
+set(TARGET_NAME Querying)
 
-add_executable(main
+project(${TARGET_NAME})
+
+# Check the build type and ask the user to set concrete one
+if (NOT CMAKE_BUILD_TYPE)
+    set(CMAKE_BUILD_TYPE RelWithDebInfo)
+    message(WARNING "CMAKE_BUILD_TYPE is not set, forcing to RelWithDebInfo")
+endif ()
+
+# Set compiler flags
+if (${CMAKE_CXX_COMPILER_ID} MATCHES "GNU" OR ${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
+    set(CMAKE_CXX_FLAGS "-std=c++17 -Wall -Wextra")
+    set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3")
+    set(CMAKE_CXX_FLAGS_RELEASE "-O3")
+    set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 -g3")
+    set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os")
+endif ()
+
+find_package(Qt5Widgets REQUIRED)
+find_package(Qt5Network REQUIRED)
+
+include_directories(
+        ${CMAKE_CURRENT_BINARY_DIR}
+        ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+# Instruct CMake to run moc automatically when needed
+set(CMAKE_AUTOMOC ON)
+
+# Add subdirectory SQLiteCpp with all necessary files
+add_subdirectory(lib/SQLiteCpp)
+
+
+# Source files
+set(SOURCES
         src/main.cpp
+        src/ui/forms/mainform.cpp
+        src/ui/widgets/textedit.cpp
         src/calculation/InvertedIndex.cpp src/calculation/InvertedIndex.h
         src/util/InvertedIndexJSONParser.cpp src/util/InvertedIndexJSONParser.h
         src/calculation/Space.cpp src/calculation/Space.h
@@ -14,6 +48,37 @@ add_executable(main
         src/calculation/Computor.cpp src/calculation/Computor.h
         src/calculation/Document.cpp src/calculation/Document.h
         src/util/QueryJSONParser.cpp src/util/QueryJSONParser.h
-        src/exceptions/Exceptions.h)
+        src/exceptions/Exceptions.h
+        src/CollectionFetcher.cpp src/CollectionFetcher.h)
+
+# User interface files
+set(FORMS
+        src/ui/forms/mainform.ui
+        )
+
+# Resource files
+set(RESOURCES
+        resources.qrc
+        )
+
+# Shared libraries
+set(LIBRARIES
+        Qt5::Widgets
+        Qt5::Network
+        SQLiteCpp
+        )
+
+# Generate additional sources with MOC and UIC
+qt5_wrap_ui(UIC_SOURCES ${FORMS})
+qt5_add_resources(RCC_SOURCES ${RESOURCES})
+
+# Set target
+add_executable(${TARGET_NAME} ${SOURCES} ${HEADERS} ${UIC_SOURCES} ${RCC_SOURCES})
+
+# Link with libraries
+target_link_libraries(${TARGET_NAME} ${LIBRARIES})
 
-target_link_libraries(main)
+# Installation
+install(TARGETS ${TARGET_NAME} RUNTIME DESTINATION bin)
+install(FILES resources/${TARGET_NAME}.png DESTINATION share/icons/hicolor/48x48/apps)
+install(FILES ${TARGET_NAME}.desktop DESTINATION share/applications)
diff --git a/querying/resources.qrc b/querying/resources.qrc
new file mode 100644
index 0000000000000000000000000000000000000000..f71680fbb8074d60c5ed7bae63fb45082785f826
--- /dev/null
+++ b/querying/resources.qrc
@@ -0,0 +1,10 @@
+<RCC>
+    <qresource prefix="/">
+        <file>resources/add-tab.png</file>
+        <file>resources/close-hover.png</file>
+        <file>resources/close.png</file>
+        <file>resources/main-icon.png</file>
+        <file>resources/swap.png</file>
+        <file>resources/settings.png</file>
+    </qresource>
+</RCC>
diff --git a/querying/resources/add-tab.png b/querying/resources/add-tab.png
new file mode 100644
index 0000000000000000000000000000000000000000..5115b7169594979eb0861c9c800887f884dddb85
Binary files /dev/null and b/querying/resources/add-tab.png differ
diff --git a/querying/resources/close-hover.png b/querying/resources/close-hover.png
new file mode 100644
index 0000000000000000000000000000000000000000..8a801d7b234c02cb5620259436a1ceacb16ace5b
Binary files /dev/null and b/querying/resources/close-hover.png differ
diff --git a/querying/resources/close.png b/querying/resources/close.png
new file mode 100644
index 0000000000000000000000000000000000000000..04962ed0b24bde6525bdb740b9ab2a00419c616b
Binary files /dev/null and b/querying/resources/close.png differ
diff --git a/querying/resources/main-icon.png b/querying/resources/main-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..b457af5274cb0d0cca7485c5c225e0f693bf082f
Binary files /dev/null and b/querying/resources/main-icon.png differ
diff --git a/querying/resources/settings.png b/querying/resources/settings.png
new file mode 100644
index 0000000000000000000000000000000000000000..c3b978f231ab4a2b45465df157919827507689b0
Binary files /dev/null and b/querying/resources/settings.png differ
diff --git a/querying/resources/swap.png b/querying/resources/swap.png
new file mode 100644
index 0000000000000000000000000000000000000000..61c63b0c8a66f86fef405a74f41ca2d762495252
Binary files /dev/null and b/querying/resources/swap.png differ
diff --git a/querying/src/CollectionFetcher.cpp b/querying/src/CollectionFetcher.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c295cdb5573fbdf236da5b14fe7ba476c43974ce
--- /dev/null
+++ b/querying/src/CollectionFetcher.cpp
@@ -0,0 +1,17 @@
+#include "CollectionFetcher.h"
+#include <SQLiteCpp/SQLiteCpp.h>
+
+using namespace std;
+
+vector<string> CollectionFetcher::fetchCollection(const string &databasePath) {
+    SQLite::Database db(databasePath);
+    SQLite::Statement query(db, "SELECT filename FROM Document");
+
+    vector<string> result;
+
+    while (query.executeStep())
+        result.emplace_back(query.getColumn(0));
+
+
+    return result;
+}
diff --git a/querying/src/CollectionFetcher.h b/querying/src/CollectionFetcher.h
new file mode 100644
index 0000000000000000000000000000000000000000..7974e18101299981d5002ee78e5851ea3448c80b
--- /dev/null
+++ b/querying/src/CollectionFetcher.h
@@ -0,0 +1,17 @@
+//
+// Created by tomas on 3/31/20.
+//
+
+#ifndef QUERYING_COLLECTIONFETCHER_H
+#define QUERYING_COLLECTIONFETCHER_H
+
+#include <vector>
+#include <string>
+
+class CollectionFetcher {
+public:
+    static std::vector<std::string> fetchCollection(const std::string &databasePath);
+};
+
+
+#endif //QUERYING_COLLECTIONFETCHER_H
diff --git a/querying/src/main.cpp b/querying/src/main.cpp
index 77aeb1416b8fb32964bab5ecc0200b2e5f514084..974544f4d72ab9095adb85483e94569ded99c11e 100644
--- a/querying/src/main.cpp
+++ b/querying/src/main.cpp
@@ -1,16 +1,25 @@
+
 #include <iostream>
+#include <map>
+
+#include <QApplication>
 
+#include "../lib/cxxopts.hpp"
 #include "calculation/Query.h"
 #include "calculation/Space.h"
 #include "calculation/Computor.h"
-#include "../lib/cxxopts.hpp"
 #include "util/QueryJSONParser.h"
 #include "util/InvertedIndexJSONParser.h"
+#include "src/ui/forms/mainform.h"
+#include "CollectionFetcher.h"
 
+static const int HELP_INDICATOR = 1;
+static const int SUCCESS_INDICATOR = 0;
+static const int FAILURE_INDICATOR = 2;
 using namespace std;
 using namespace cxxopts;
 
-int main(int argc, char **argv) {
+pair<int, string> parseArguments(int argc, char **argv) {
     Options options("Information retrieval - querying", "Queries against a collection.");
     options.add_options()
             ("c,collection", "Document collection", cxxopts::value<string>())
@@ -18,13 +27,52 @@ int main(int argc, char **argv) {
 
     auto result = options.parse(argc, argv);
 
-    if (result.count("help")) {
-        cout << options.help() << std::endl;
-        return EXIT_SUCCESS;
-    }
+    if (result.count("help"))
+        return {HELP_INDICATOR, options.help()};
 
     if (!result.count("collection"))
-        return EXIT_FAILURE;
+        return {FAILURE_INDICATOR, ""};
+
+    return {SUCCESS_INDICATOR, result["collection"].as<string>()};
+}
+
+int main(int argc, char *argv[]) {
+
+    auto arg = parseArguments(argc, argv);
+    switch (arg.first) {
+        case SUCCESS_INDICATOR: {
+            break;
+        }
+        case HELP_INDICATOR : {
+            cout << arg.second << endl;
+            return EXIT_SUCCESS;
+
+        }
+        case FAILURE_INDICATOR: {
+            //todo error message
+            return EXIT_FAILURE;
+        }
+    }
+
+    Space space(InvertedIndexJSONParser(arg.second).parse());
+
+    auto availableDocuments = CollectionFetcher::fetchCollection("../../data/persistence/docs_and_terms.db");
+
+    QApplication application(argc, argv);
+
+    MainForm mainForm;
+    mainForm
+            .setAvailableDocuments(availableDocuments)
+            .setResults({"a", "b", "c"})
+            .setOpenedDocument(availableDocuments[0]);
+    mainForm.show();
+
+
+    return QApplication::exec();
+}
+
+/*
+int main(int argc, char **argv) {
 
     auto collectionPath = result["collection"].as<string>();
     Space space(InvertedIndexJSONParser(collectionPath).parse());
@@ -47,3 +95,4 @@ int main(int argc, char **argv) {
 
     return EXIT_SUCCESS;
 }
+*/
diff --git a/querying/src/ui/forms/mainform.cpp b/querying/src/ui/forms/mainform.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..204dc8d1b66203c8f8bcaa9e123e5443551a643d
--- /dev/null
+++ b/querying/src/ui/forms/mainform.cpp
@@ -0,0 +1,101 @@
+#include "mainform.h"
+#include "ui_mainform.h"
+
+#include <QMenu>
+#include <QToolButton>
+#include <QtCore/QFile>
+#include <QtCore/QTextStream>
+
+
+MainForm::MainForm(QWidget *parent) :
+        QMainWindow(parent),
+        UI(new Ui::MainForm),
+        documentsList(new QListWidget()),
+        resultsList(new QListWidget()),
+        openedDocument(new QTextBrowser()) {
+    setupUi();
+}
+
+
+MainForm::~MainForm() {
+    delete UI;
+    delete documentsList;
+    delete resultsList;
+    delete openedDocument;
+}
+
+
+void MainForm::setupUi() {
+    UI->setupUi(this);
+
+    setWindowIcon(QIcon(":/resources/main-icon.png"));
+    setWindowTitle("Querying: Vector model of information retrieval");
+
+    trayIcon.setIcon(QIcon(":/resources/main-icon.png"));
+    trayIcon.show();
+
+    connect(&trayIcon,
+            SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
+            SLOT(onTrayIconActivated(QSystemTrayIcon::ActivationReason)));
+
+    UI->statusBar->hide();
+
+    UI->toolBar->setIconSize(QSize(24, 24));
+    UI->toolBar->setFloatable(false);
+    UI->toolBar->setMovable(false);
+}
+
+
+void MainForm::onTrayIconActivated(QSystemTrayIcon::ActivationReason reason) {
+    if (reason == QSystemTrayIcon::Trigger) {
+        setVisible(!isVisible());
+    } else if (reason == QSystemTrayIcon::Context) {
+        QMenu menu;
+
+        if (isVisible()) {
+            menu.addAction("Minimize", this, SLOT(hide()));
+        } else {
+            menu.addAction("Restore", this, SLOT(show()));
+        }
+
+        menu.addAction(settingsAction);
+
+        menu.addSeparator();
+        menu.addAction("Quit", qApp, SLOT(quit()));
+        menu.exec(QCursor::pos());
+    }
+}
+
+MainForm &MainForm::setAvailableDocuments(const std::vector<std::string> &documents) {
+    QStringList dummy;
+
+    for (const auto &doc : documents)
+        dummy.append(QString(doc.data()));
+
+    UI->documentsList->addItems(dummy);
+    return *this;
+}
+
+MainForm &MainForm::setResults(const std::vector<std::string> &results) {
+    QStringList dummy;
+
+    for (const auto &result : results)
+        dummy.append(QString(result.data()));
+
+    UI->resultsList->addItems(dummy);
+
+    return *this;
+}
+
+MainForm &MainForm::setOpenedDocument(const std::string &documentPath) {
+    QString path = QString::fromStdString(documentPath);
+
+    QFile file(path);
+
+    file.open(QIODevice::ReadOnly);
+    UI->documentBrowser->setText(QTextStream(&file).readAll());
+    file.close();
+
+
+    return *this;
+}
diff --git a/querying/src/ui/forms/mainform.h b/querying/src/ui/forms/mainform.h
new file mode 100644
index 0000000000000000000000000000000000000000..e68b179b8d4968dbf43ba4115b6180ea38fed165
--- /dev/null
+++ b/querying/src/ui/forms/mainform.h
@@ -0,0 +1,51 @@
+#ifndef MAINFORM_H
+#define MAINFORM_H
+
+#include <QMainWindow>
+#include <QSystemTrayIcon>
+
+#include <string>
+#include <vector>
+#include <QtWidgets/QListView>
+#include <QtCore/QStringListModel>
+#include <QtWidgets/QListWidget>
+#include <QtWidgets/QTextBrowser>
+
+namespace Ui {
+    class MainForm;
+}
+
+
+class MainForm : public QMainWindow {
+Q_OBJECT
+public:
+    explicit MainForm(QWidget *parent = nullptr);
+
+    ~MainForm() override;
+
+    MainForm &setAvailableDocuments(const std::vector<std::string> &documents);
+
+    MainForm &setResults(const std::vector<std::string> &results);
+
+    MainForm &setOpenedDocument(const std::string &documentPath);
+
+private:
+    Ui::MainForm *UI;
+    QSystemTrayIcon trayIcon;
+
+    QAction *settingsAction;
+
+    QListWidget *documentsList;
+    QListWidget *resultsList;
+    QTextBrowser *openedDocument;
+
+    void setupUi();
+
+private slots:
+
+    void onTrayIconActivated(QSystemTrayIcon::ActivationReason reason);
+
+};
+
+
+#endif // MAINFORM_H
diff --git a/querying/src/ui/forms/mainform.ui b/querying/src/ui/forms/mainform.ui
new file mode 100644
index 0000000000000000000000000000000000000000..24e6779dd540cc38d12c07ae29ed78ec8ce5f8b3
--- /dev/null
+++ b/querying/src/ui/forms/mainform.ui
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainForm</class>
+ <widget class="QMainWindow" name="MainForm">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>430</width>
+    <height>447</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>MainForm</string>
+  </property>
+  <widget class="QWidget" name="centralWidget">
+   <layout class="QVBoxLayout" name="horizontalLayout">
+    <property name="leftMargin">
+     <number>2</number>
+    </property>
+    <property name="topMargin">
+     <number>2</number>
+    </property>
+    <property name="rightMargin">
+     <number>2</number>
+    </property>
+    <property name="bottomMargin">
+     <number>2</number>
+    </property>
+    <item>
+     <widget class="QListWidget" name="documentsList"/>
+    </item>
+    <item>
+     <widget class="QTextBrowser" name="documentBrowser"/>
+    </item>
+    <item>
+     <widget class="QListWidget" name="resultsList"/>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QMenuBar" name="menuBar">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>430</width>
+     <height>25</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QToolBar" name="toolBar">
+   <attribute name="toolBarArea">
+    <enum>TopToolBarArea</enum>
+   </attribute>
+   <attribute name="toolBarBreak">
+    <bool>false</bool>
+   </attribute>
+  </widget>
+  <widget class="QStatusBar" name="statusBar"/>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/querying/src/ui/widgets/textedit.cpp b/querying/src/ui/widgets/textedit.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d9cc63dd1ca13b0f7ab94d858e96adbd73ec1521
--- /dev/null
+++ b/querying/src/ui/widgets/textedit.cpp
@@ -0,0 +1,29 @@
+#include "textedit.h"
+
+#include <QDebug>
+#include <QKeyEvent>
+
+
+TextEdit::TextEdit(QWidget* parent) :
+	QPlainTextEdit(parent)
+{
+
+}
+
+
+TextEdit::~TextEdit()
+{
+
+}
+
+
+void TextEdit::keyPressEvent(QKeyEvent* e)
+{
+	if(e->key() == Qt::Key_Escape) {
+		clear();
+	}
+	else {
+		QPlainTextEdit::keyPressEvent(e);
+	}
+}
+
diff --git a/querying/src/ui/widgets/textedit.h b/querying/src/ui/widgets/textedit.h
new file mode 100644
index 0000000000000000000000000000000000000000..ee3bae7f5c3cc086ca2791ebd30365ff5bad9f21
--- /dev/null
+++ b/querying/src/ui/widgets/textedit.h
@@ -0,0 +1,18 @@
+#ifndef TEXTEDIT_H
+#define TEXTEDIT_H
+
+#include <QPlainTextEdit>
+
+
+class TextEdit : public QPlainTextEdit {
+	Q_OBJECT
+public:
+	TextEdit(QWidget* parent = nullptr);
+	~TextEdit();
+
+private:
+	void keyPressEvent(QKeyEvent* e);
+};
+
+
+#endif // TEXTEDIT_H