Let the Database-class handle the data.

This commit is contained in:
tastytea 2019-01-12 21:24:09 +01:00
parent 0fdaad70ee
commit d9065280ea
Signed by: tastytea
GPG Key ID: CFC39497F1B26E07
6 changed files with 110 additions and 107 deletions

View File

@ -33,6 +33,8 @@ MainWindow::MainWindow(QMainWindow *parent)
: QMainWindow(parent) : QMainWindow(parent)
, _config("whyblocked.cfg") , _config("whyblocked.cfg")
, _headersize({ 250, 125, 125 }) , _headersize({ 250, 125, 125 })
, _database()
, _dbdata(_database.get_data())
{ {
std::locale::global(std::locale("")); std::locale::global(std::locale(""));
@ -198,7 +200,7 @@ void MainWindow::populate_tableview(const vector<Database::data> &entries)
void MainWindow::reload() void MainWindow::reload()
{ {
_dbdata = Database::query(); _database.reload();
populate_tableview(_dbdata); populate_tableview(_dbdata);
} }
@ -221,7 +223,7 @@ void MainWindow::add_row(const QString &user, const int &blocked,
void MainWindow::add() void MainWindow::add()
{ {
DialogAdd *dialog = new DialogAdd(this); DialogAdd *dialog = new DialogAdd(_database, this);
dialog->show(); dialog->show();
} }
@ -234,24 +236,14 @@ void MainWindow::edit()
return; return;
} }
DialogAdd *dialog = new DialogAdd(this); DialogAdd *dialog = new DialogAdd(_database, this);
dialog->setWindowTitle(tr("Edit entry")); dialog->setWindowTitle(tr("Edit entry"));
QModelIndex index = tableview->selectionModel()->selectedRows().first(); QModelIndex index = tableview->selectionModel()->selectedRows().first();
const string user = index.sibling(index.row(), 0).data() const string user = index.sibling(index.row(), 0).data()
.toString().toStdString(); .toString().toStdString();
Database::data data; dialog->set_data(_database.get_user(user));
for (const Database::data &entry : _dbdata)
{
if (entry.user == user)
{
data = entry;
break;
}
}
dialog->set_data(data);
dialog->setProperty("edit", true); dialog->setProperty("edit", true);
dialog->show(); dialog->show();
} }
@ -264,7 +256,7 @@ void MainWindow::remove()
for (auto &row : selection->selectedRows()) for (auto &row : selection->selectedRows())
{ {
const string user = row.data().toString().toStdString(); const string user = row.data().toString().toStdString();
Database::remove(user); _database.remove(user);
_model->removeRow(row.row()); _model->removeRow(row.row());
} }
label_receipts->clear(); label_receipts->clear();
@ -347,15 +339,7 @@ void MainWindow::show_details(QModelIndex index)
{ {
const string user = index.sibling(index.row(), 0).data() const string user = index.sibling(index.row(), 0).data()
.toString().toStdString(); .toString().toStdString();
Database::data data; Database::data data = _database.get_user(user);
for (const Database::data &entry : _dbdata)
{
if (entry.user == user)
{
data = entry;
break;
}
}
string text = ""; string text = "";
if (!data.receipts.empty()) if (!data.receipts.empty())
@ -408,16 +392,17 @@ void MainWindow::dropEvent(QDropEvent *event)
} }
} }
DialogAdd *dialog = new DialogAdd(this); DialogAdd *dialog = new DialogAdd(_database, this);
Database::data data; Database::data data;
data.user = text; data.user = text;
dialog->set_data(data); dialog->set_data(data);
dialog->show(); dialog->show();
} }
DialogAdd::DialogAdd(QMainWindow *parent) DialogAdd::DialogAdd(Database &database, QMainWindow *parent)
: QDialog(parent) : QDialog(parent)
, _parent(static_cast<MainWindow*>(parent)) , _parent(static_cast<MainWindow*>(parent))
, _database(database)
{ {
setupUi(this); setupUi(this);
} }
@ -478,18 +463,15 @@ void DialogAdd::accept()
} }
Database::data data = get_data(); Database::data data = get_data();
if (data.user.empty()) if (!data)
{ {
return; return;
} }
Database::add_user(data.user, data.blocked, data.reason);
_database.add_user(data);
_parent->add_row(QString::fromStdString(data.user), _parent->add_row(QString::fromStdString(data.user),
data.blocked, data.blocked,
QString::fromStdString(data.reason)); QString::fromStdString(data.reason));
for (const string &receipt : data.receipts)
{
Database::add_receipt(data.user, receipt);
}
delete this; delete this;
} }

View File

@ -33,14 +33,6 @@
using std::string; using std::string;
using std::vector; using std::vector;
// struct Dialogdata
// {
// string user = "";
// bool blocked = true;
// string reason = "";
// std::vector<string> receipts = {};
// };
class MainWindow : public QMainWindow, private Ui::MainWindow class MainWindow : public QMainWindow, private Ui::MainWindow
{ {
Q_OBJECT Q_OBJECT
@ -63,7 +55,8 @@ private:
QStandardItemModel *_model; QStandardItemModel *_model;
xdgcfg _config; xdgcfg _config;
std::array<int, 3> _headersize; std::array<int, 3> _headersize;
std::vector<Database::data> _dbdata; Database _database;
std::vector<Database::data> &_dbdata;
private slots: private slots:
void add(); void add();
@ -81,7 +74,7 @@ class DialogAdd : public QDialog, private Ui::DialogAdd
Q_OBJECT Q_OBJECT
public: public:
explicit DialogAdd(QMainWindow *parent = nullptr); explicit DialogAdd(Database &database, QMainWindow *parent = nullptr);
void set_data(const Database::data &data); void set_data(const Database::data &data);
private: private:
@ -90,6 +83,7 @@ private:
void dropEvent(QDropEvent *event); void dropEvent(QDropEvent *event);
MainWindow *_parent; MainWindow *_parent;
Database &_database;
private slots: private slots:
void add_receipt(); void add_receipt();

View File

@ -17,7 +17,7 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <vector> #include <vector>
#include <tuple> #include <iterator>
#include <experimental/filesystem> #include <experimental/filesystem>
#include <basedir.h> #include <basedir.h>
#include <sqlite/connection.hpp> #include <sqlite/connection.hpp>
@ -33,7 +33,7 @@ Database::data::operator bool() const
return !user.empty(); return !user.empty();
} }
const string Database::get_filepath() const string Database::get_filepath() const
{ {
fs::path filepath; fs::path filepath;
xdgHandle xdg; xdgHandle xdg;
@ -58,38 +58,30 @@ const string Database::get_filepath()
return filepath; return filepath;
} }
bool Database::add_user(const string &user, const bool blocked, bool Database::add_user(const Database::data &userdata)
const string &reason)
{ {
try try
{ {
int blocked_int = 0; int blocked_int = 0;
if (blocked) if (userdata.blocked)
{ {
blocked_int = 1; blocked_int = 1;
} }
sqlite::connection con(get_filepath()); sqlite::connection con(get_filepath());
sqlite::execute ins(con, "INSERT INTO blocks VALUES(?, ?, ?);"); {
ins % user % blocked_int % reason; sqlite::execute ins(con, "INSERT INTO blocks VALUES(?, ?, ?);");
ins(); ins % userdata.user % blocked_int % userdata.reason;
} ins();
catch (const std::exception &e) }
{ {
cerr << "An error occurred: " << e.what() << std::endl; for (const string &receipt : userdata.receipts)
return false; {
} sqlite::execute ins(con, "INSERT INTO urls VALUES(?, ?);");
ins % userdata.user % receipt;
return true; ins();
} }
}
bool Database::add_receipt(const string &user, const string &receipt) _data.push_back(userdata);
{
try
{
sqlite::connection con(get_filepath());
sqlite::execute ins(con, "INSERT INTO urls VALUES(?, ?);");
ins % user % receipt;
ins();
} }
catch (const std::exception &e) catch (const std::exception &e)
{ {
@ -111,6 +103,7 @@ bool Database::remove(const string &user)
rm_urls % user; rm_urls % user;
rm_blocks(); rm_blocks();
rm_urls(); rm_urls();
reload();
} }
catch (const std::exception &e) catch (const std::exception &e)
{ {
@ -121,7 +114,7 @@ bool Database::remove(const string &user)
return true; return true;
} }
const vector<Database::data> Database::query(const string &sql_query) const vector<Database::data> Database::query(const string &sql_query) const
{ {
try try
{ {
@ -167,3 +160,34 @@ const vector<Database::data> Database::query(const string &sql_query)
return {}; return {};
} }
} }
bool Database::reload()
{
auto buffer = query();
if (buffer.empty())
{
return false;
}
else
{
_data = std::move(buffer);
return true;
}
}
std::vector<Database::data> &Database::get_data()
{
return _data;
}
const Database::data Database::get_user(const string &user) const
{
for (const Database::data &entry : _data)
{
if (entry.user == user)
{
return entry;
}
}
return {};
}

View File

@ -18,7 +18,6 @@
#define WHYBLOCKED_HPP #define WHYBLOCKED_HPP
#include <vector> #include <vector>
#include <tuple>
#include <string> #include <string>
using std::string; using std::string;
@ -37,15 +36,19 @@ public:
explicit operator bool() const; explicit operator bool() const;
}; };
static bool add_user(const string &user, const bool blocked, bool add_user(const data &userdata);
const string &reason); bool remove(const string &user);
static bool add_receipt(const string &user, const string &receipt); const vector<data> query(const string &sql_query =
static bool remove(const string &user); "SELECT * FROM blocks;") const;
static const vector<data> query(const string &sql_query = bool reload();
"SELECT * FROM blocks;"); std::vector<data> &get_data();
const data get_user(const string &user) const;
private: private:
static const string get_filepath(); std::vector<data> _data;
private:
const string get_filepath() const;
}; };
#endif // WHYBLOCKED_HPP #endif // WHYBLOCKED_HPP

View File

@ -74,7 +74,7 @@
<translation>Du kannst URLs hier hineinziehen</translation> <translation>Du kannst URLs hier hineinziehen</translation>
</message> </message>
<message> <message>
<location filename="../src/interface_qt.cpp" line="465"/> <location filename="../src/interface_qt.cpp" line="444"/>
<source>Insert receipt here.</source> <source>Insert receipt here.</source>
<translation>Beleg hier einfügen.</translation> <translation>Beleg hier einfügen.</translation>
</message> </message>
@ -198,7 +198,7 @@
</message> </message>
<message> <message>
<location filename="../src/whyblocked.ui" line="285"/> <location filename="../src/whyblocked.ui" line="285"/>
<location filename="../src/interface_qt.cpp" line="238"/> <location filename="../src/interface_qt.cpp" line="240"/>
<source>Edit entry</source> <source>Edit entry</source>
<translation>Eintrag bearbeiten</translation> <translation>Eintrag bearbeiten</translation>
</message> </message>
@ -219,68 +219,68 @@
</message> </message>
<message> <message>
<location filename="../src/whyblocked.ui" line="59"/> <location filename="../src/whyblocked.ui" line="59"/>
<location filename="../src/interface_qt.cpp" line="183"/> <location filename="../src/interface_qt.cpp" line="185"/>
<source>User/Instance</source> <source>User/Instance</source>
<translation>Benutzer/Instanz</translation> <translation>Benutzer/Instanz</translation>
</message> </message>
<message> <message>
<location filename="../src/interface_qt.cpp" line="184"/> <location filename="../src/interface_qt.cpp" line="186"/>
<source>Blocked/Silenced</source> <source>Blocked/Silenced</source>
<translation>Blockiert/Gedämpft</translation> <translation>Blockiert/Gedämpft</translation>
</message> </message>
<message> <message>
<location filename="../src/whyblocked.ui" line="72"/> <location filename="../src/whyblocked.ui" line="72"/>
<location filename="../src/interface_qt.cpp" line="185"/> <location filename="../src/interface_qt.cpp" line="187"/>
<source>Reason</source> <source>Reason</source>
<translation>Begründung</translation> <translation>Begründung</translation>
</message> </message>
<message> <message>
<location filename="../src/interface_qt.cpp" line="109"/> <location filename="../src/interface_qt.cpp" line="111"/>
<source>Try dragging an account from your webbrowser into this window.</source> <source>Try dragging an account from your webbrowser into this window.</source>
<translation>Versuche, einen account von deinem webbrowser in dieses fenster zu ziehen.</translation> <translation>Versuche, einen account von deinem webbrowser in dieses fenster zu ziehen.</translation>
</message> </message>
<message> <message>
<location filename="../src/interface_qt.cpp" line="212"/> <location filename="../src/interface_qt.cpp" line="214"/>
<source>blocked</source> <source>blocked</source>
<translation>blockiert</translation> <translation>blockiert</translation>
</message> </message>
<message> <message>
<location filename="../src/interface_qt.cpp" line="216"/> <location filename="../src/interface_qt.cpp" line="218"/>
<source>silenced</source> <source>silenced</source>
<translation>gedämpft</translation> <translation>gedämpft</translation>
</message> </message>
<message> <message>
<location filename="../src/interface_qt.cpp" line="232"/> <location filename="../src/interface_qt.cpp" line="234"/>
<source>Invalid selection</source> <source>Invalid selection</source>
<translation>Ungültige Auswahl</translation> <translation>Ungültige Auswahl</translation>
</message> </message>
<message> <message>
<location filename="../src/interface_qt.cpp" line="233"/> <location filename="../src/interface_qt.cpp" line="235"/>
<source>Please select only 1 entry to edit.</source> <source>Please select only 1 entry to edit.</source>
<translation>Bitte nur 1 Eintrag zum bearbeiten auswählen.</translation> <translation>Bitte nur 1 Eintrag zum bearbeiten auswählen.</translation>
</message> </message>
<message> <message>
<location filename="../src/interface_qt.cpp" line="274"/> <location filename="../src/interface_qt.cpp" line="266"/>
<source>Nothing selected</source> <source>Nothing selected</source>
<translation>Nichts ausgewählt</translation> <translation>Nichts ausgewählt</translation>
</message> </message>
<message> <message>
<location filename="../src/interface_qt.cpp" line="275"/> <location filename="../src/interface_qt.cpp" line="267"/>
<source>Please select entries to remove.</source> <source>Please select entries to remove.</source>
<translation>Bitte wähle einträge aus, die gelöscht werden sollen.</translation> <translation>Bitte wähle einträge aus, die gelöscht werden sollen.</translation>
</message> </message>
<message> <message>
<location filename="../src/interface_qt.cpp" line="339"/> <location filename="../src/interface_qt.cpp" line="325"/>
<source>About Whyblocked</source> <source>About Whyblocked</source>
<translation>Über Whyblocked</translation> <translation>Über Whyblocked</translation>
</message> </message>
<message> <message>
<location filename="../src/interface_qt.cpp" line="340"/> <location filename="../src/interface_qt.cpp" line="326"/>
<source>&lt;p&gt;&lt;b&gt;Whyblocked&lt;/b&gt; %1&lt;/p&gt;&lt;p&gt;Reminds you why you blocked someone.&lt;/p&gt;&lt;p&gt;Sourcecode: &lt;a href=&quot;https://schlomp.space/tastytea/whyblocked&quot;&gt;https://schlomp.space/tastytea/whyblocked&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;small&gt;Copyright © 2018 &lt;a href=&quot;mailto:tastytea@tastytea.de&quot;&gt;tastytea&lt;/a&gt;.&lt;br&gt;Licence GPLv3: &lt;a href=&quot;https://www.gnu.org/licenses/gpl-3.0.html&quot;&gt;GNU GPL version 3&lt;/a&gt;.&lt;br&gt;This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions.&lt;/small&gt;&lt;/p&gt;</source> <source>&lt;p&gt;&lt;b&gt;Whyblocked&lt;/b&gt; %1&lt;/p&gt;&lt;p&gt;Reminds you why you blocked someone.&lt;/p&gt;&lt;p&gt;Sourcecode: &lt;a href=&quot;https://schlomp.space/tastytea/whyblocked&quot;&gt;https://schlomp.space/tastytea/whyblocked&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;small&gt;Copyright © 2018 &lt;a href=&quot;mailto:tastytea@tastytea.de&quot;&gt;tastytea&lt;/a&gt;.&lt;br&gt;Licence GPLv3: &lt;a href=&quot;https://www.gnu.org/licenses/gpl-3.0.html&quot;&gt;GNU GPL version 3&lt;/a&gt;.&lt;br&gt;This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions.&lt;/small&gt;&lt;/p&gt;</source>
<translation>&lt;p&gt;&lt;b&gt;Whyblocked&lt;/b&gt; %1&lt;/p&gt;&lt;p&gt;Erinnert dich, warum du jemanden blockiertest.&lt;/p&gt;&lt;p&gt;Quelltext: &lt;a href=&quot;https://schlomp.space/tastytea/whyblocked&quot;&gt;https://schlomp.space/tastytea/whyblocked&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;small&gt;Copyright © 2018 &lt;a href=&quot;mailto:tastytea@tastytea.de&quot;&gt;tastytea&lt;/a&gt;.&lt;br&gt;Lizenz GPLv3: &lt;a href=&quot;https://www.gnu.org/licenses/gpl-3.0.html&quot;&gt;GNU GPL version 3&lt;/a&gt;.&lt;br&gt;Für dieses Programm besteht KEINERLEI GARANTIE. Dies ist freie Software, die Sie unter bestimmten Bedingungen weitergeben dürfen.&lt;/small&gt;&lt;/p&gt;</translation> <translation>&lt;p&gt;&lt;b&gt;Whyblocked&lt;/b&gt; %1&lt;/p&gt;&lt;p&gt;Erinnert dich, warum du jemanden blockiertest.&lt;/p&gt;&lt;p&gt;Quelltext: &lt;a href=&quot;https://schlomp.space/tastytea/whyblocked&quot;&gt;https://schlomp.space/tastytea/whyblocked&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;small&gt;Copyright © 2018 &lt;a href=&quot;mailto:tastytea@tastytea.de&quot;&gt;tastytea&lt;/a&gt;.&lt;br&gt;Lizenz GPLv3: &lt;a href=&quot;https://www.gnu.org/licenses/gpl-3.0.html&quot;&gt;GNU GPL version 3&lt;/a&gt;.&lt;br&gt;Für dieses Programm besteht KEINERLEI GARANTIE. Dies ist freie Software, die Sie unter bestimmten Bedingungen weitergeben dürfen.&lt;/small&gt;&lt;/p&gt;</translation>
</message> </message>
<message> <message>
<location filename="../src/interface_qt.cpp" line="369"/> <location filename="../src/interface_qt.cpp" line="347"/>
<source>Receipts:</source> <source>Receipts:</source>
<translation>Belege:</translation> <translation>Belege:</translation>
</message> </message>

View File

@ -74,7 +74,7 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/interface_qt.cpp" line="465"/> <location filename="../src/interface_qt.cpp" line="444"/>
<source>Insert receipt here.</source> <source>Insert receipt here.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -198,7 +198,7 @@
</message> </message>
<message> <message>
<location filename="../src/whyblocked.ui" line="285"/> <location filename="../src/whyblocked.ui" line="285"/>
<location filename="../src/interface_qt.cpp" line="238"/> <location filename="../src/interface_qt.cpp" line="240"/>
<source>Edit entry</source> <source>Edit entry</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -219,68 +219,68 @@
</message> </message>
<message> <message>
<location filename="../src/whyblocked.ui" line="59"/> <location filename="../src/whyblocked.ui" line="59"/>
<location filename="../src/interface_qt.cpp" line="183"/> <location filename="../src/interface_qt.cpp" line="185"/>
<source>User/Instance</source> <source>User/Instance</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/interface_qt.cpp" line="184"/> <location filename="../src/interface_qt.cpp" line="186"/>
<source>Blocked/Silenced</source> <source>Blocked/Silenced</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/whyblocked.ui" line="72"/> <location filename="../src/whyblocked.ui" line="72"/>
<location filename="../src/interface_qt.cpp" line="185"/> <location filename="../src/interface_qt.cpp" line="187"/>
<source>Reason</source> <source>Reason</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/interface_qt.cpp" line="109"/> <location filename="../src/interface_qt.cpp" line="111"/>
<source>Try dragging an account from your webbrowser into this window.</source> <source>Try dragging an account from your webbrowser into this window.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/interface_qt.cpp" line="212"/> <location filename="../src/interface_qt.cpp" line="214"/>
<source>blocked</source> <source>blocked</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/interface_qt.cpp" line="216"/> <location filename="../src/interface_qt.cpp" line="218"/>
<source>silenced</source> <source>silenced</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/interface_qt.cpp" line="232"/> <location filename="../src/interface_qt.cpp" line="234"/>
<source>Invalid selection</source> <source>Invalid selection</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/interface_qt.cpp" line="233"/> <location filename="../src/interface_qt.cpp" line="235"/>
<source>Please select only 1 entry to edit.</source> <source>Please select only 1 entry to edit.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/interface_qt.cpp" line="274"/> <location filename="../src/interface_qt.cpp" line="266"/>
<source>Nothing selected</source> <source>Nothing selected</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/interface_qt.cpp" line="275"/> <location filename="../src/interface_qt.cpp" line="267"/>
<source>Please select entries to remove.</source> <source>Please select entries to remove.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/interface_qt.cpp" line="339"/> <location filename="../src/interface_qt.cpp" line="325"/>
<source>About Whyblocked</source> <source>About Whyblocked</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/interface_qt.cpp" line="340"/> <location filename="../src/interface_qt.cpp" line="326"/>
<source>&lt;p&gt;&lt;b&gt;Whyblocked&lt;/b&gt; %1&lt;/p&gt;&lt;p&gt;Reminds you why you blocked someone.&lt;/p&gt;&lt;p&gt;Sourcecode: &lt;a href=&quot;https://schlomp.space/tastytea/whyblocked&quot;&gt;https://schlomp.space/tastytea/whyblocked&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;small&gt;Copyright © 2018 &lt;a href=&quot;mailto:tastytea@tastytea.de&quot;&gt;tastytea&lt;/a&gt;.&lt;br&gt;Licence GPLv3: &lt;a href=&quot;https://www.gnu.org/licenses/gpl-3.0.html&quot;&gt;GNU GPL version 3&lt;/a&gt;.&lt;br&gt;This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions.&lt;/small&gt;&lt;/p&gt;</source> <source>&lt;p&gt;&lt;b&gt;Whyblocked&lt;/b&gt; %1&lt;/p&gt;&lt;p&gt;Reminds you why you blocked someone.&lt;/p&gt;&lt;p&gt;Sourcecode: &lt;a href=&quot;https://schlomp.space/tastytea/whyblocked&quot;&gt;https://schlomp.space/tastytea/whyblocked&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;small&gt;Copyright © 2018 &lt;a href=&quot;mailto:tastytea@tastytea.de&quot;&gt;tastytea&lt;/a&gt;.&lt;br&gt;Licence GPLv3: &lt;a href=&quot;https://www.gnu.org/licenses/gpl-3.0.html&quot;&gt;GNU GPL version 3&lt;/a&gt;.&lt;br&gt;This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions.&lt;/small&gt;&lt;/p&gt;</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/interface_qt.cpp" line="369"/> <location filename="../src/interface_qt.cpp" line="347"/>
<source>Receipts:</source> <source>Receipts:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>