WSC ist in Arbeit

Ach ja, schon wieder ein neues Projekt. Wobei es nicht ganz richtig ist. Genau genommen ist es noch das Projekt Horizont unter einem neuen Namen. Im Prinzip kann ich daraus auch Horizont später ableiten, mit wahrscheinlich nur wenigen Änderungen. Es ist also auch ein kleines, soziales Netzwerk, doch mit dem Ziel, die Leute aus meinem Wifesharing-Blog besser zu vernetzen.

Um was geht es?

Ziel des Ganzen soll ein soziales Netzwerk werden, welches, anders als bislang üblich, komplett auf einen Browser verzichtet. Mit ein Problem dabei wird natürlich sein, es muss für möglichst alle Plattformen verfügbar sein. Also Linux (klar, damit wird es entwickelt), Windows, Android, aber auch MacOS und iOS, oder heissen die jetzt beide iOS?

Im Fokus liegt derzeit Linux und Windows. Beides 64-Bit natürlich. Dann soll es zu Android gehen und was Apple angeht, da ich keine Hardware und auch kein PC mit diesem OS habe, wird das natürlich schwieriger. Abwarten!

Natürlich ist das ganze kostenlos und Daten werden auch keine Verkauft. Wüsste zum Einen nicht an wen, zum Anderen wage ich es zu bezweifeln, dass da genug Informationen bei rumkommen, als dass die wirklich von Bedeutung wären. Also in der Hinsicht ist in diesem Netz nichts zu befürchten.

Darüber hinaus versuche ich auch alles möglichst so zu regeln, dass es auch mit den kommenden Urheberrechtsgesetzen in Einklang steht.

Ausserdem, was eigentlich mehr durch Zufall entstanden ist, WSC wird Templates unterstützen! Das heisst, wer sich berufen fühlt, kann der Software ein eigenes Aussehen verpassen und dieses dann auch veröffentlichen, damit auch andere Nutzer etwas davon haben.

Was soll WSC bieten?

Bieten soll WSC die Kommunikation für Gleichgesinnte. Also jene, die sich mit dem Thema auseinandersetzen.

Dabei gibt es drei grundlegende Funktionen:

  • Notizblock
  • Gruppen / Gruppenchat
  • Privater Chat

Der Notizblock

Der Notizblock soll das Äquivalent des Streams werden. Dort werden die neusten Beiträge von den Leuten der Freundesliste angezeigt und man kann eigene verfassen. Kommentare abgeben, liken und was eben dazugehört.

Gruppen und Gruppenchat

Wichtig in einer solchen Community sind natürlich Gruppen. Nach Plan sollen die von den Benutzern selbst erstellt und gepflegt werden können. Bestandteile jeder Gruppe sind zu Beginn natürlich der Notizblock und Chat der Gruppe. In späteren Versionen kann es natürlich auch noch erweitert werden. Je nach Bedarf.

Ich will aber sofort anmerken, Gruppen werden NICHT verschlüsselt! Das mag jetzt kontraproduktiv wirken, aber ich habe keinen Bedarf, irgendwelche illegalen Aktivitäten zu unterstützen, was eine verschlüsselte Gruppe in einem wenig, oder fast unbekannten Netzwerk natürlich unterstützen würde. Von daher, Gruppen können bei Bedarf eingesehen werden!

Privater Chat

Ein privater Chat bedeutet eine Kommunikation zwischen zwei Personen. Dieser Chat wird definitiv verschlüsselt! Eingesetzt wird dabei OpenSSL mit asymmetrischer Verschlüsselung (4096 Bit).

Hier dürfte auch einer der grössten Unterschiede zu anderen sozialen Netzwerken liegen. Diese verwenden in aller Regel ja den Browser als Oberfläche. Das heisst, niemand kann mit Sicherheit sagen, wer die Nachrichten dort schon abfangen kann, bevor sie verschickt, oder verschlüsselt werden. Beim WSC wird das anders. Da werden alle Nachrichten auf dem lokalen Rechner verschlüsselt und erst dann an den Server übertragen (End – End Verschlüsselung)! Im Umkehrschluss werden die Nachrichten erst auf den lokalen Computer geladen und dann erst entschlüsselt. Der Klartext ist also definitiv nur beim Sender und Empfänger zu sehen!

Um das realisieren zu können, generiert WSC bei der Registrierung automatisch ein Schlüsselpaar und speichert den öffentlichen Schlüssel auf dem Server. Der Private bleibt immer auf dem lokalen Rechner und wird NIE übertragen!

Was bietet WSC (noch) nicht?

Man sollte bedenken, ich entwickle diese Software alleine und auch ehrenamtlich. Das da nicht von Anfang an ein Funktionsumfang dabei ist, wie man ihn aus etablierten Systemen her kennt, dürfte klar sein. Deshalb sollte es auch nicht verwunderlich sein, wenn dieses soziale Netzwerk am Anfang etwas rudimentär daherkommt. Hoffentlich schreckt das nicht zu viele Leute ab. Die Zeit wird es zeigen.

Was definitiv noch nicht in Version 1 zu finden sein wird, sind Emojis und die Möglichkeit Bilder zu übertragen. Das liegt jedoch nicht an meiner Unfähigkeit, sondern viel mehr daran, erst einmal eine stabile Plattform zu schaffen! Das heisst, sowohl das Versenden von Bildern, wie auch die Nutzung von Emojis ist definitiv auf der Liste! Das wird also kommen, insofern das System keine Totgeburt wird!

Was noch alles fehlen wird, wird sich noch zeigen. Aber ich sage es jetzt schon. Findet das System Anklang, werde ich es auch weiterentwickeln und auf Wünsche der Nutzer eingehen!

Das benötigt WSC

Nicht sonderlich viel und nichts davon kostet Geld. Insofern man einen Computer mit Linux, oder Windows sein Eigen nennt.

Abhängig wird WSC, zumindest aus aktueller Sicht, nur von zwei Komponenten sein.

  • Qt
  • OpenSSL
  • Sodium

Also, alles locker, alles kostenlos.

Stand der Dinge

Das mag ja alles gut klingen und sich nach einer super Vision anhören. Davon gibt es aber schon genug. Um zu zeigen, dass es sich dabei nicht um ein Hirngespinst handelt, hier der aktuelle Stand der Version 0.1:

Linux-Version
Windows-Version

Kann zwar noch nichts, aber wie man sieht, es existiert bereits! Ist vielleicht nicht das schönste Design, wie aber schon weiter oben angemerkt, dass Design kann geändert werden.

Bildbetrachter in C/C++ und QT

Kürzlich habe ich mit der Nutzung von QT als grafische Benutzeroberfläche begonnen. Eigentlich wundert es mich, dass ich darum immer so einen grossen Bogen gemacht habe, denn eigentlich tut es genau das, was ich von einem solchen ToolKit verlange! Wahrscheinlich liegt es daran, dass ich aus irgendeinem Grund der Meinung war, QT-Oberflächen müsste man mit dem QT–Creator bauen. Aber egal.

Nun bliebe natürlich die Frage, warum mache ich das? Das Netz ist voll solcher Beschreibungen. Das ist eigentlich ganz einfach. Ich habe es bei Nana gesehen. Das habe ich in letzter Zeit zum erstellen grafischer Benutzeroberflächen eingesetzt und war soweit auch ganz zufrieden damit. Aber da war immer mal wieder das Problem, habe ich eine Zeit nicht damit gearbeitet, ging mir viel verloren und ich durfte wieder nachschauen. Jetzt, bei QT, notiere ich eben alles hier und wer weiss, vielleicht helfe ich damit ja jemandem.

Es sollte klar sein, dass man QT installiert haben muss, damit es funktioniert. Wie man das bei der jeweiligen Distribution macht, oder unter Windows, müsst ihr selbst herausfinden. Ja, Windows sollte auch funktionieren. Habe ich noch nicht versucht, aber werde ich in diesem Projekt hier machen!

Ziel dieses Artikels

Am Ende dieses Artikels soll es möglich sein, dass Programm, welches ich dubb nennen werde (diabolus Umarov Bildbetrachter) , in der Eingabeaufforderung mit einem Parameter zu starten. Der Parameter soll, wer hätte es gedacht, die Bilddatei angeben. Natürlich soll diese dann angezeigt werden.

Der Beginn von dubb

Ich verwende als IDE Visual Studio Code. Ja, ein Microsoft-Produkt. Damit bestätige ich auch, was ich gerne behaupte. Ich bin durchaus dazu in der Lage, Produkte dieser Firma zu nutzen, wenn sie mir gefallen! Dazu verwende ich auch noch cmake und clang.

Zuerst brauche ich ein Verzeichnis, indem ich arbeiten kann. Das nenne ich einfach dubb und öffne es in VCode.

Als nächstes muss ich das Projekt anlegen. Das ist recht simpel mit shift+strg+p. Oben öffnet sich ein Drop-Down-Menü und da wähle ich CMake: Quick Start aus. Im Anschluss dann Clang 8.0.0 …, gebe dubb als Projekt-Name ein und wähle schliesslich Executable aus. Schon wird das Projekt erstellt und die Datei CMakeLists.txt geöffnet, in der folgendes drinsteht:

cmake_minimum_required(VERSION 3.0.0)
project(dubb VERSION 0.1.0)

include(CTest)
enable_testing()

add_executable(dubb main.cpp)

set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

Ausserdem wird noch die Datei main.cpp erstellt. Ich teste einfach mal, ob alles funktioniert hat und ändere dafür diese Datei etwas ab. Einfach so, dass das berühmte Hallo Welt! erscheint. Das sieht dann so aus:

#include <iostream>

using namespace std;

int main(int argc, char* argv[]) 
{
    cout << "Hallo Welt!" << endl;
}

Im Prinzip hätte ich die Vorgabe so lassen können, denn die hat genau das gemacht. Doch ich bin da eigen! Egal, den Krempel compiliere ich jetzt und dann schaue ich, ob es auch brach funktioniert hat!

$ ./dubb 
Hallo Welt!

Hervorragend. Klappt ja soweit alles!

Klappt das aber auch mit dem Parameter?

argv[0] wäre der Name des Programms. Das heisst, ich schaue mal was argv[1] zurückgibt.

#include <iostream>

using namespace std;

int main(int argc, char* argv[]) 
{
    cout << argv[1] << endl;
}

Und das Ergebnis ist:

$ ./dubb hallo
hallo

Perfekt!

Nun ran an QT

Ich will aber eine grafische Oberfläche haben und dafür will ich QT einsetzen. Da ich es echt nicht schön finde, wenn ich alles in einer Datei hängen habe und ich auch nicht weiss, wie gross diese Geschichte überhaupt wird, fange ich mal an weitere Dateien zu erstellen und diese dann mit entsprechendem Code zu füllen.

Zuerst einmal die Datei windows.h. Da kommen alle Klassen und so rein.

#include <QMainWindow>

class HauptWindow : public QMainWindow
{
    Q_OBJECT

    public:
        HauptWindow();

    private slots:

    private:
};

Als Grundgerüst funktioniert das. Aber, so wird der Compiler ganz laut schreien! Denn, da muss noch was in der CMakeLists.txt eingetragen werden, die dann so aussieht:

cmake_minimum_required(VERSION 3.0.0)
project(dubb VERSION 0.1.0)

find_package(Qt5 COMPONENTS Widgets REQUIRED)
find_package(Qt5Core REQUIRED)

include(CTest)
enable_testing()

add_executable(dubb main.cpp)

set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

target_link_libraries(dubb Qt5::Widgets)

Und schon klappts auch mit dem Nachbarn! Aber, so bringt das alles überhaupt nichts! Das Fenster muss noch geöffnet und gefüllt werden usw. Also erst einmal das Fenster!

Das könnte ich nun alles in die windows.h Datei schreiben, was bei diesem Programm wohl auch kein Problem wäre. Ich bevorzuge es jedoch anders und erstelle dafür wieder eine neue Datei mit dem Namen hauptwindow.h. Da kommen dann die Funktionen rein, die das Fenster betreffen und natürlich muss das auch alles noch eingebunden werden.

Für den Anfang reicht es mir, wenn sich das Fenster öffnet und ich es auch wieder schliessen kann. Da ich noch nicht genau weiss, in welche Richtung sich das Projekt entwickeln wird, werde ich die Funktion zum schliessen mit QAction definierten. Das muss natürlich zuerst in der Klasse auch definiert werden und das sieht dann so aus in der windows.h:

#include <QMainWindow>
#include <QAction>

class HauptWindow : public QMainWindow
{
    Q_OBJECT

    public:
        HauptWindow();

    private slots:
        void beenden();

    private:
        QAction *beendenAction;
};

Die Datei hauptwindow.h sieht dann so aus und tut nichts anderes, als dem Fenster die Möglichkeit einzuräumen, auch wieder geschlossen werden zu zu können.

HauptWindow::HauptWindow()
{
    beendenAction = new QAction(tr("&Beenden"));

    connect(beendenAction, SIGNAL (triggered()), this, SLOT (beenden()));   
}

void HauptWindow::beenden()
{
    qApp->quit();
}

Okay. Also muss nur noch etwas her, um das Fenster auch nach dem Programmstart zu zeigen! Das kommt in main.cpp.

#include <iostream>
#include <QApplication>

#include "windows.h"

using namespace std;

#include "hauptwindow.h"

int main(int argc, char* argv[]) 
{
    QApplication app(argc, argv);

    HauptWindow hw;

    hw.show();

    return app.exec();
}

Ausserdem muss ich die Datei CMakeLists.txt anpassen und die sieht dann so aus:

cmake_minimum_required(VERSION 3.0.0)
project(dubb VERSION 0.1.0)

set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)

find_package(Qt5 COMPONENTS Widgets REQUIRED)
find_package(Qt5Core REQUIRED)

include(CTest)
enable_testing()

add_executable(dubb main.cpp windows.h hauptwindow.h)

set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

target_link_libraries(dubb Qt5::Widgets)

So. Los Compiler, mach deine Arbeit! Hat das alles funktioniert, kommt folgendes bei raus:

Alles richtig gemacht, in nur ganz wenigen Schritten. QT gefällt mir! Erinnert mich in gewisser Hinsicht an MUI auf dem AmigaOS! Ausserdem, wie ein Test zeigt, schliesst sich das Fenster auch brav wieder, wenn man das X im Titel anklickt.

Das mit dem Bild

Nun gut. So toll das Fenster ja sein mag, es nutzt mir überhaupt nichts! Das dumme Ding soll schliesslich ein vorher ausgewähltes Bild zeigen!

Im Prinzip könnte ich jetzt einfach den Wert von argv[1] nehmen, damit das Bild laden und anzeigen lassen. Aber eben, ich habe noch keine Ahnung, wie weit dieses Projekt noch anwachsen wird und deshalb will ich vorbereitet sein. Im Prinzip heisst das nichts anderes, als dass ich eine Klasse für das anzuzeigende Bild anlege. Die ist super banal und speichert nur den Pfad und den Dateiname. Aber wer weiss, wo das noch hinführt, da bin ich lieber vorbereitet.

Also mal wieder eine neue Datei und die bekommt den überaus gelungenen Namen bild.h.

class Bild
{
    private:
        string file;

    public:

        void setFile(char *f)
        {
            file = f;
        }

        QString getFile()
        {
            return QString::fromStdString(file);
        }
};

Jede Wette, man kann es auch viel besser machen, aber ich mache es eben so weil ich weiss, dass es funktioniert!

Jetzt muss ich noch main.cpp anpassen, dass argv[1] in die Klasse gespeichert wird. Ach ja, natürlich muss ich ja auch noch auf die Klasse zugreifen können und zwar auch aus den anderen Dateien heraus. Dann sieht das so aus:

#include <iostream>
#include <QApplication>

#include "windows.h"

using namespace std;

#include "bild.h"

Bild bild;

#include "hauptwindow.h"

int main(int argc, char* argv[]) 
{
    bild.setFile(argv[1]);

    QApplication app(argc, argv);

    HauptWindow hw;

    hw.show();

    return app.exec();
}

Das nützt aber auch noch nichts, denn nur weil ich jetzt eine Datei als Variable in einer Klasse speichern und wieder abrufen kann, wird hier noch gar nichts angezeigt. Also, irgendwas muss ich auch damit machen können!

Dafür bauche ich ein paar Dinge. Zum Einen muss das Bild ja irgendwie geladen auch noch irgendwie im Fenster angezeigt werden. Also, ran ans Werk!

Zum Anzeigen verwende ich einfach ein QLabel. Ist es die beste Variante? Keine Ahnung, aber egal. Dafür ändere ich dann natürlich wieder windows.h sowie hauptwindow.h. In dieser Reihenfolge.

#include <QMainWindow>
#include <QAction>
#include <QLabel>
#include <QPixmap>

class HauptWindow : public QMainWindow
{
    Q_OBJECT

    public:
        HauptWindow();

    private slots:
        void beenden();

    private:
        QAction *beendenAction;

        QLabel *bildLabel;

        QPixmap bildPixmap;
};

und

HauptWindow::HauptWindow()
{
    bildLabel = new QLabel();

    bildPixmap.load(bild.getFile());

    bildLabel->setPixmap(bildPixmap);

    beendenAction = new QAction(tr("&Beenden"));

    connect(beendenAction, SIGNAL (triggered()), this, SLOT (beenden()));   

    setCentralWidget(bildLabel);
}

void HauptWindow::beenden()
{
    qApp->quit();
}

Lasset uns schauen, ob die Nummer auch funktioniert!

Ja da schau an, es hat funktioniert! Zumindest zum Teil. Ja, das Bild wird angezeigt. Aber, es ändert die Grösse mit demFenster. Im Prinzip ist das ja nicht schlimm, aber was wenn man ein Bild hat, was grösser ist als die Auflösung? Oder wenn man das Fenster skaliert? Also da muss noch was dran!

Ich könnte es mir nun einfach machen und das Label einfach so einstellen, dass es seinen Inhalt bei Grössenveränderungen skaliert. Dazu müsste ich nur folgendes in der hauptwindow.h einbauen:

bildLabel->setScaledContents(true);

Das wäre aber nicht das Gelbe vom Ei, denn dann würde sich das Bild unter Umständen verziehen. Es soll aber sein Verhältnis beibehalten! Das heisst also mehr Arbeit! Zum Einen muss ich ein Event einbauen, welches auf eine Veränderung der Grösse reagiert. Dort muss ich dann die Grösse des Bildes ermitteln, es unter Beibehaltung seines Verhältnisses skalieren und damit erst die Grösse von bildLabel anpassen. Ausserdem soll ja auch alles schön mittig angezeigt werden, weshalb ich bildLabel auch noch in ein QHBoxLayout packe. Das bedeutet Änderungen in windows.h und natürlich auch in haupwindow.h. Das sieht dann so aus:

#include <QMainWindow>
#include <QAction>
#include <QLabel>
#include <QPainter>
#include <QPixmap>
#include <QHBoxLayout>

class HauptWindow : public QMainWindow
{
    Q_OBJECT

    public:
        HauptWindow();
        void resizeEvent(QResizeEvent* event);

    private slots:
        void beenden();

    private:
        QAction *beendenAction;

        QHBoxLayout *mainBox;
        
        QLabel *bildLabel;

        QPainter *bildPainter;

        QPixmap bildPixmap;
};
HauptWindow::HauptWindow()
{
    mainBox = new QHBoxLayout();
    QWidget *mainLayout = new QWidget();

    bildPixmap.load(bild.getFile());

    bildLabel = new QLabel();

    bildPainter = new QPainter(bildLabel);

    bildLabel->setPixmap(bildPixmap);
    bildLabel->setScaledContents(true);
    bildLabel->setAlignment(Qt::AlignCenter);

    beendenAction = new QAction(tr("&Beenden"));

    connect(beendenAction, SIGNAL (triggered()), this, SLOT (beenden()));   

    mainBox->addWidget(bildLabel);
    mainBox->setAlignment(Qt::AlignCenter);

    mainLayout->setLayout(mainBox);

    setCentralWidget(mainLayout);
}

void HauptWindow::beenden()
{
    qApp->quit();
}

void HauptWindow::resizeEvent(QResizeEvent* event)        
{
    QSize ls = bildLabel->size();
    QSize bs;

    QPixmap neuPixmap = bildPixmap.scaled(ls, Qt::KeepAspectRatio);

    bs = neuPixmap.size();

    bildLabel->resize(bs);
}

War das erfolgreich? Das wird ein Test zeigen!

Das nenne ich dann jetzt einfach mal Erfolg! Nicht ganz perfekt, da das Bild in einigen Fenstern durchaus auch grösser sein könnte, aber für den Anfang reicht es und ich behaupte einfach mal, damit ist das Ziel dieses Artikels auch erreicht.

Aber damit ist die Sache noch nicht beendet. Weitere Teile werden folgen!

BlunsenLabs auf dem Yakumo

Der Artikel wird nicht lang, deshalb auch kein Inhaltsverzeichnis. Tatsächlich tippe ich ihn gerade auf meinem Yakumo Laptop der tatsächlich nur einen Celeron M Prozessor mit 1.300 MHz verwendet! Trotzdem muss ich sagen, es geht eigentlich wirklich gut! Ich tippe und die Buchstaben sind tatsächlich sofort zusehen! Da kann ich überhaupt nicht meckern!

Krass finde ich auch, der Laptop hat laut Conky 490 MB Arbeitsspeicher. Also nach heutigen Verhältnisen mehr als wenig. Dennoch läuft gerade Chromium und ich habe gerade einmal 250 MB davon in Gebrauch. Schon eine Marke!

Ich muss aber auch sagen, die Leistung ist jetzt nicht besser als unter Gentoo. Aber eben auch nicht schlechter. Die Installation hat keine Stunde gedauert und im Anschluss lief die Kiste sofort! Auch ein komplettes Systemupdate dauerte nur Minuten. Unter Gentoo mehrere Stunden!

BunsenLabs wird wohl nie Gentoo für mich ersetzen und den Sprung auf mein eigentliches Arbeitsgerät schaffen. Aber ich spiele mit dem Gedanken, BL auch auf meinem NetBook einzusetzen! Dort bin ich zwar mit der Arbeitsleistung zufrieden, aber die Updates dauern einfach ewig!

Was mir bei der Installation aufgefallen ist, zum Einen es gibt nur eine Text-Basierte Installation. Die ist aber das Gleiche wie die mit grafischer Oberfläche, da gibt es also keine Probleme. Dazu wollte die Installation wissen, ob ich mittels Kabel, oder W-Lan verbunden werden will. Ich habe mal spasseshalber W-Lan ausgewählt und siehe da, die Verbindung funktionierte einwandfrei! Dickes Plus!

So. Das reicht erst einmal für den Augenblick. Ich bin definitiv begeistert von BunsenLabs und kann nur sagen, ältere Rechner laufen damit noch ziemlich gut! Wie gesagt, hier jetzt den Artikel tippen ist absolut kein Problem!