mirror of
https://github.com/theCheeseboard/thedesk.git
synced 2025-01-22 10:22:02 -05:00
Make lock screen work
This commit is contained in:
parent
9bc03dd3bb
commit
7bf5795701
17 changed files with 592 additions and 95 deletions
|
@ -1,2 +1,3 @@
|
|||
add_subdirectory(locker-common)
|
||||
add_subdirectory(locker-ui)
|
||||
add_subdirectory(locker-checker)
|
||||
|
|
|
@ -12,5 +12,6 @@ cntp_target_name(locker-checker "td-locker-checker")
|
|||
target_link_libraries(locker-checker Qt::Core crypt)
|
||||
|
||||
install(TARGETS locker-checker
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE SETUID
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
BUNDLE DESTINATION /Applications)
|
||||
|
|
|
@ -1,61 +1,78 @@
|
|||
#include <QCommandLineParser>
|
||||
#include <QCoreApplication>
|
||||
#include <QCryptographicHash>
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
QCoreApplication::setSetuidAllowed(true);
|
||||
QCoreApplication a(argc, argv);
|
||||
|
||||
QCommandLineParser parser;
|
||||
parser.addHelpOption();
|
||||
parser.addPositionalArgument("username", "Username to check the password of", "<username>");
|
||||
parser.process(a);
|
||||
|
||||
QFile shadow("/etc/shadow");
|
||||
QStringList arguments = a.arguments();
|
||||
if (arguments.contains("--help")) {
|
||||
qDebug() << "tchkpass - Check User Password";
|
||||
qDebug() << "Usage: checkpassword user password";
|
||||
qDebug() << "";
|
||||
qDebug() << "--help Shows this help";
|
||||
qDebug() << "";
|
||||
qDebug() << "This command needs to be run as root.";
|
||||
return 2;
|
||||
}
|
||||
|
||||
shadow.open(QFile::ReadOnly);
|
||||
if (!shadow.isReadable()) {
|
||||
qDebug() << "Can't read the shadow file.";
|
||||
qDebug() << "This command needs to be run as root.";
|
||||
QTextStream(stderr) << "Can't read the shadow file.\n";
|
||||
QTextStream(stderr) << "This command needs to be run as root.\n";
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (parser.positionalArguments().count() < 1) {
|
||||
QTextStream(stderr) << "Not enough arguments\n";
|
||||
return 2;
|
||||
}
|
||||
|
||||
// TODO: THIS IS BAD.
|
||||
// We should not be reading the shadow file directly.
|
||||
// Consider invoking PAM
|
||||
QStringList shadowFile(QString(shadow.readAll()).split("\n"));
|
||||
for (QString user : shadowFile) {
|
||||
if (user.startsWith(arguments.at(1))) {
|
||||
QString hashedPassword = user.split(":").at(1);
|
||||
for (const QString& user : shadowFile) {
|
||||
auto parts = user.split(":");
|
||||
if (parts.length() < 2) continue;
|
||||
|
||||
if (parts.constFirst() == parser.positionalArguments().at(0)) {
|
||||
QString hashedPassword = parts.at(1);
|
||||
QStringList passwordParts = hashedPassword.split("$");
|
||||
if (passwordParts.count() == 1) {
|
||||
qDebug() << "No password.";
|
||||
QTextStream(stdout) << "No password.\n";
|
||||
return 0;
|
||||
} else if (passwordParts.count() != 4) {
|
||||
QTextStream(stdout) << "Unable to parse shadow file\n";
|
||||
return 2;
|
||||
} else {
|
||||
if (arguments.count() < 3) {
|
||||
qDebug() << "Not enough arguments";
|
||||
return 1;
|
||||
}
|
||||
// QString tryPassword(QCryptographicHash::hash(arguments.at(2).toUtf8(), QCryptographicHash::Sha512));
|
||||
const char* characters = (crypt(arguments.at(2).toStdString().c_str(), QString("$" + passwordParts.at(1) + "$" + passwordParts.at(2)).toStdString().c_str()));
|
||||
QTextStream in(stdin, QIODevice::ReadOnly);
|
||||
|
||||
// Turn off echo
|
||||
struct termios term;
|
||||
tcgetattr(fileno(stdin), &term);
|
||||
|
||||
term.c_lflag &= ~ECHO;
|
||||
tcsetattr(fileno(stdin), 0, &term);
|
||||
|
||||
QTextStream(stderr) << "Password: ";
|
||||
|
||||
const char* characters = (crypt(in.readLine().toUtf8().data(), QString("$" + passwordParts.at(1) + "$" + passwordParts.at(2)).toStdString().c_str()));
|
||||
QString encryptedPass(characters);
|
||||
|
||||
// QString hashedPass(QCryptographicHash::hash(encryptedPass.toUtf8(), QCryptographicHash::Sha512));
|
||||
QTextStream(stderr) << "\n";
|
||||
|
||||
if (encryptedPass.split("$").at(3) == passwordParts.at(3)) {
|
||||
qDebug() << "Password correct";
|
||||
QTextStream(stdout) << "Password correct\n";
|
||||
return 0;
|
||||
} else {
|
||||
qDebug() << "Password incorrect";
|
||||
QTextStream(stderr) << "Password incorrect\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
QTextStream(stderr) << "Unable to find user in shadow file\n";
|
||||
return 2;
|
||||
}
|
||||
|
|
21
locker/locker-common/CMakeLists.txt
Normal file
21
locker/locker-common/CMakeLists.txt
Normal file
|
@ -0,0 +1,21 @@
|
|||
project(locker VERSION 1.0.0 LANGUAGES CXX)
|
||||
|
||||
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core)
|
||||
find_package(libcontemporary REQUIRED)
|
||||
cntp_find_pkgconfig(X11 x11)
|
||||
|
||||
set(SOURCES
|
||||
lockergrabs.cpp
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
lockergrabs.h
|
||||
)
|
||||
|
||||
add_library(locker-common STATIC ${SOURCES} ${HEADERS})
|
||||
target_link_libraries(locker-common Qt::Core libcontemporary)
|
||||
|
||||
IF(${X11_FOUND})
|
||||
target_link_libraries(locker-common PkgConfig::X11)
|
||||
target_compile_definitions(locker-common PRIVATE HAVE_X11)
|
||||
ENDIF()
|
25
locker/locker-common/lockergrabs.cpp
Normal file
25
locker/locker-common/lockergrabs.cpp
Normal file
|
@ -0,0 +1,25 @@
|
|||
#include "lockergrabs.h"
|
||||
|
||||
#ifdef HAVE_X11
|
||||
#include <tx11info.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#endif
|
||||
|
||||
void LockerGrabs::establishGrab() {
|
||||
#ifdef HAVE_X11
|
||||
if (tX11Info::isPlatformX11()) {
|
||||
XGrabKeyboard(tX11Info::display(), tX11Info::appRootWindow(), True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||
XGrabPointer(tX11Info::display(), tX11Info::appRootWindow(), True, None, GrabModeAsync, GrabModeAsync, tX11Info::appRootWindow(), None, CurrentTime);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void LockerGrabs::releaseGrab() {
|
||||
#ifdef HAVE_X11
|
||||
if (tX11Info::isPlatformX11()) {
|
||||
XUngrabKeyboard(tX11Info::display(), CurrentTime);
|
||||
XUngrabPointer(tX11Info::display(), CurrentTime);
|
||||
}
|
||||
#endif
|
||||
}
|
9
locker/locker-common/lockergrabs.h
Normal file
9
locker/locker-common/lockergrabs.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
#ifndef LOCKERGRABS_H
|
||||
#define LOCKERGRABS_H
|
||||
|
||||
namespace LockerGrabs {
|
||||
void establishGrab();
|
||||
void releaseGrab();
|
||||
}; // namespace LockerGrabs
|
||||
|
||||
#endif // LOCKERGRABS_H
|
|
@ -3,14 +3,19 @@ project(locker VERSION 1.0.0 LANGUAGES CXX)
|
|||
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets DBus Sql PrintSupport)
|
||||
find_package(libcontemporary REQUIRED)
|
||||
find_package(libtdesktopenvironment REQUIRED)
|
||||
cntp_find_pkgconfig(X11 x11)
|
||||
|
||||
set(SOURCES
|
||||
main.cpp
|
||||
mainwindow.cpp mainwindow.ui
|
||||
underlineanimation.cpp
|
||||
lockmanager.cpp
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
mainwindow.h
|
||||
underlineanimation.h
|
||||
lockmanager.h
|
||||
)
|
||||
|
||||
add_executable(locker-ui ${SOURCES} ${HEADERS})
|
||||
|
@ -26,8 +31,8 @@ cntp_init(locker-ui 20)
|
|||
cntp_translate(locker-ui)
|
||||
cntp_target_name(locker-ui "td-locker")
|
||||
|
||||
target_link_libraries(locker-ui Qt::Widgets Qt::DBus Qt::Sql Qt::PrintSupport libcontemporary libtdesktopenvironment libthedesk)
|
||||
target_include_directories(locker-ui PUBLIC ../libthedesk/)
|
||||
target_link_libraries(locker-ui Qt::Widgets Qt::DBus Qt::Sql Qt::PrintSupport libcontemporary libtdesktopenvironment libthedesk locker-common)
|
||||
target_include_directories(locker-ui PUBLIC ../locker-common/)
|
||||
|
||||
install(TARGETS locker-ui
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
|
|
61
locker/locker-ui/lockmanager.cpp
Normal file
61
locker/locker-ui/lockmanager.cpp
Normal file
|
@ -0,0 +1,61 @@
|
|||
#include "lockmanager.h"
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include <QTimer>
|
||||
#include <Screens/screendaemon.h>
|
||||
#include <Screens/systemscreen.h>
|
||||
#include <Wm/desktopwm.h>
|
||||
#include <lockergrabs.h>
|
||||
|
||||
struct LockManagerPrivate {
|
||||
QList<MainWindow*> openWindows;
|
||||
QTimer* grabTimer;
|
||||
};
|
||||
|
||||
LockManager* LockManager::instance() {
|
||||
static auto manager = new LockManager();
|
||||
return manager;
|
||||
}
|
||||
|
||||
void LockManager::openLockWindows() {
|
||||
for (auto window : d->openWindows) {
|
||||
window->close();
|
||||
window->deleteLater();
|
||||
}
|
||||
d->openWindows.clear();
|
||||
|
||||
for (auto screen : ScreenDaemon::instance()->screens()) {
|
||||
auto* w = new MainWindow();
|
||||
w->setWindowFlags(Qt::WindowStaysOnTopHint);
|
||||
w->show();
|
||||
w->setGeometry(screen->geometry());
|
||||
w->showFullScreen();
|
||||
d->openWindows.append(w);
|
||||
}
|
||||
}
|
||||
|
||||
void LockManager::establishGrab() {
|
||||
LockerGrabs::establishGrab();
|
||||
}
|
||||
|
||||
void LockManager::raiseAll() {
|
||||
for (auto w : d->openWindows) {
|
||||
w->raise();
|
||||
}
|
||||
}
|
||||
|
||||
LockManager::LockManager(QObject* parent) :
|
||||
QObject{parent} {
|
||||
d = new LockManagerPrivate();
|
||||
|
||||
connect(ScreenDaemon::instance(), &ScreenDaemon::screensUpdated, this, &LockManager::openLockWindows);
|
||||
openLockWindows();
|
||||
|
||||
d->grabTimer = new QTimer();
|
||||
d->grabTimer->setInterval(5000);
|
||||
connect(d->grabTimer, &QTimer::timeout, this, &LockManager::establishGrab);
|
||||
connect(d->grabTimer, &QTimer::timeout, this, &LockManager::raiseAll);
|
||||
d->grabTimer->start();
|
||||
|
||||
establishGrab();
|
||||
}
|
24
locker/locker-ui/lockmanager.h
Normal file
24
locker/locker-ui/lockmanager.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
#ifndef LOCKMANAGER_H
|
||||
#define LOCKMANAGER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
struct LockManagerPrivate;
|
||||
class LockManager : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static LockManager* instance();
|
||||
|
||||
void openLockWindows();
|
||||
void establishGrab();
|
||||
void raiseAll();
|
||||
|
||||
signals:
|
||||
|
||||
private:
|
||||
explicit LockManager(QObject* parent = nullptr);
|
||||
|
||||
LockManagerPrivate* d;
|
||||
};
|
||||
|
||||
#endif // LOCKMANAGER_H
|
|
@ -17,7 +17,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* *************************************/
|
||||
#include "mainwindow.h"
|
||||
#include "lockmanager.h"
|
||||
|
||||
#include <tapplication.h>
|
||||
|
||||
|
@ -37,8 +37,7 @@ int main(int argc, char* argv[]) {
|
|||
|
||||
a.registerCrashTrap();
|
||||
|
||||
MainWindow w;
|
||||
w.show();
|
||||
LockManager::instance();
|
||||
|
||||
int retval = a.exec();
|
||||
return retval;
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
#include <QCoroProcess>
|
||||
#include <QProcess>
|
||||
#include <SystemSlide/systemslide.h>
|
||||
#include <Wm/desktopwm.h>
|
||||
#include <lockmanager.h>
|
||||
#include <terrorflash.h>
|
||||
|
||||
struct MainWindowPrivate {
|
||||
QString lockCheckProcess;
|
||||
|
@ -29,25 +32,20 @@ MainWindow::MainWindow(QWidget* parent) :
|
|||
d->lockCheckProcess = "/usr/lib/td-locker-checker"; // TODO: Don't hardcode
|
||||
}
|
||||
|
||||
connect(d->slide, &SystemSlide::deactivated, this, [this]() -> QCoro::Task<> {
|
||||
ui->usernameLabel->setText(DesktopWm::userDisplayName());
|
||||
ui->capsLockOn->setVisible(false);
|
||||
|
||||
connect(d->slide, &SystemSlide::deactivated, this, [this] {
|
||||
if (this->checkPassword("")) {
|
||||
QApplication::exit(0);
|
||||
return;
|
||||
}
|
||||
|
||||
// tPropertyAnimation* opacity = new tPropertyAnimation(passwordFrameOpacity, "opacity");
|
||||
// opacity->setStartValue(0.0);
|
||||
// opacity->setEndValue(1.0);
|
||||
// opacity->setDuration(500);
|
||||
// opacity->setEasingCurve(QEasingCurve::OutCubic);
|
||||
// connect(opacity, SIGNAL(finished()), opacity, SLOT(deleteLater()));
|
||||
// opacity->start();
|
||||
ui->password->setFocus();
|
||||
|
||||
// QTimer::singleShot(100, this, [ = ] {
|
||||
// ui->MouseUnderline->startAnimation();
|
||||
// ui->PasswordUnderline->startAnimation();
|
||||
// });
|
||||
|
||||
// ui->password->setFocus();
|
||||
QTimer::singleShot(100, this, [this] {
|
||||
ui->PasswordUnderline->startAnimation();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -68,6 +66,33 @@ bool MainWindow::checkPassword(QString password) {
|
|||
|
||||
QProcess checker;
|
||||
checker.start(d->lockCheckProcess, {name});
|
||||
checker.write(password.toUtf8());
|
||||
checker.write("\n");
|
||||
checker.closeWriteChannel();
|
||||
checker.waitForFinished();
|
||||
return checker.exitCode() == 0;
|
||||
}
|
||||
|
||||
void MainWindow::on_unlockButton_clicked() {
|
||||
this->setEnabled(false);
|
||||
if (checkPassword(ui->password->text())) {
|
||||
QApplication::exit(0);
|
||||
return;
|
||||
}
|
||||
|
||||
this->setEnabled(true);
|
||||
ui->password->setText("");
|
||||
ui->password->setFocus();
|
||||
|
||||
tErrorFlash::flashError(ui->password);
|
||||
}
|
||||
|
||||
void MainWindow::on_password_returnPressed() {
|
||||
ui->unlockButton->click();
|
||||
}
|
||||
|
||||
void MainWindow::changeEvent(QEvent* event) {
|
||||
if (event->type() == QEvent::ActivationChange) {
|
||||
LockManager::instance()->raiseAll();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,11 +18,19 @@ class MainWindow : public QMainWindow {
|
|||
private slots:
|
||||
void on_titleLabel_backButtonClicked();
|
||||
|
||||
void on_unlockButton_clicked();
|
||||
|
||||
void on_password_returnPressed();
|
||||
|
||||
private:
|
||||
Ui::MainWindow* ui;
|
||||
MainWindowPrivate* d;
|
||||
|
||||
bool checkPassword(QString password);
|
||||
|
||||
// QWidget interface
|
||||
protected:
|
||||
void changeEvent(QEvent* event);
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
|
|
@ -38,17 +38,215 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>580</height>
|
||||
</size>
|
||||
<property name="topMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
</spacer>
|
||||
<property name="rightMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item row="1" column="0">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QFrame" name="lockFrame">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>500</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="usernameLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>15</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">Username</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring></cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>20</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Please enter your password</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_14">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="password">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>30</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="capsLockOn">
|
||||
<property name="toolTip">
|
||||
<string>Caps Lock is on</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">Caps Lock is on</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="unlockButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="go-next"/>
|
||||
</property>
|
||||
<property name="default">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="UnderlineAnimation" name="PasswordUnderline" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
@ -62,6 +260,12 @@
|
|||
<slot>backButtonClicked()</slot>
|
||||
</slots>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>UnderlineAnimation</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>underlineanimation.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
|
|
@ -5,23 +5,35 @@
|
|||
<name>MainWindow</name>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="14"/>
|
||||
<location filename="../../../../build-thedesk-Chroot_6-Debug/locker/locker-ui/locker-ui_autogen/include/ui_mainwindow.h" line="59"/>
|
||||
<location filename="../../../../build-thedesk-Chroot_6-Debug/locker/locker-ui/locker-ui_autogen/include/ui_mainwindow.h" line="188"/>
|
||||
<source>MainWindow</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="36"/>
|
||||
<location filename="../../../../build-thedesk-Chroot_6-Debug/locker/locker-ui/locker-ui_autogen/include/ui_mainwindow.h" line="60"/>
|
||||
<location filename="../../../../build-thedesk-Chroot_6-Debug/locker/locker-ui/locker-ui_autogen/include/ui_mainwindow.h" line="189"/>
|
||||
<source>Unlock Session</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="22"/>
|
||||
<location filename="../mainwindow.ui" line="137"/>
|
||||
<location filename="../../../../build-thedesk-Chroot_6-Debug/locker/locker-ui/locker-ui_autogen/include/ui_mainwindow.h" line="190"/>
|
||||
<source>Please enter your password</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="197"/>
|
||||
<location filename="../../../../build-thedesk-Chroot_6-Debug/locker/locker-ui/locker-ui_autogen/include/ui_mainwindow.h" line="192"/>
|
||||
<source>Caps Lock is on</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="25"/>
|
||||
<source>Unlock</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="22"/>
|
||||
<location filename="../mainwindow.cpp" line="25"/>
|
||||
<source>Resume your session, continuing where you left off</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
|
45
locker/locker-ui/underlineanimation.cpp
Normal file
45
locker/locker-ui/underlineanimation.cpp
Normal file
|
@ -0,0 +1,45 @@
|
|||
#include "underlineanimation.h"
|
||||
|
||||
UnderlineAnimation::UnderlineAnimation(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
anim1 = new tVariantAnimation();
|
||||
anim1->setStartValue(0);
|
||||
anim1->setEndValue(this->width() / 2);
|
||||
anim1->setDuration(500);
|
||||
anim1->setEasingCurve(QEasingCurve::OutCubic);
|
||||
connect(anim1, &tVariantAnimation::valueChanged, [=](QVariant value) {
|
||||
this->repaint();
|
||||
});
|
||||
|
||||
QColor col = this->palette().color(QPalette::WindowText).toRgb();
|
||||
anim2 = new tVariantAnimation();
|
||||
anim2->setStartValue(col);
|
||||
|
||||
col.setAlpha(0);
|
||||
anim2->setEndValue(col);
|
||||
anim2->setDuration(500);
|
||||
anim2->setEasingCurve(QEasingCurve::OutCubic);
|
||||
}
|
||||
|
||||
QSize UnderlineAnimation::sizeHint() const {
|
||||
return QSize(20, 1);
|
||||
}
|
||||
|
||||
void UnderlineAnimation::startAnimation() {
|
||||
anim1->setEndValue(this->width() / 2);
|
||||
anim1->start();
|
||||
|
||||
anim2->setCurrentTime(0);
|
||||
//QTimer::singleShot(500, [=] {
|
||||
anim2->start();
|
||||
//});
|
||||
}
|
||||
|
||||
void UnderlineAnimation::paintEvent(QPaintEvent *event) {
|
||||
QPainter p(this);
|
||||
p.setPen(Qt::transparent);
|
||||
p.setBrush(anim2->currentValue().value<QColor>());
|
||||
|
||||
int mid = this->width() / 2;
|
||||
p.drawRect(mid - anim1->currentValue().toInt(), 0, anim1->currentValue().toInt() * 2, this->height());
|
||||
}
|
29
locker/locker-ui/underlineanimation.h
Normal file
29
locker/locker-ui/underlineanimation.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef UNDERLINEANIMATION_H
|
||||
#define UNDERLINEANIMATION_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QPaintEvent>
|
||||
#include <tvariantanimation.h>
|
||||
#include <QPainter>
|
||||
#include <QTimer>
|
||||
|
||||
class UnderlineAnimation : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit UnderlineAnimation(QWidget *parent = nullptr);
|
||||
|
||||
|
||||
QSize sizeHint() const;
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
void startAnimation();
|
||||
|
||||
private:
|
||||
void paintEvent(QPaintEvent* event);
|
||||
|
||||
tVariantAnimation *anim1, *anim2;
|
||||
};
|
||||
|
||||
#endif // UNDERLINEANIMATION_H
|
|
@ -1,55 +1,66 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="nl">
|
||||
<context>
|
||||
<context>
|
||||
<name>PenButton</name>
|
||||
<message>
|
||||
<translation>Supergum</translation>
|
||||
<location filename="../penbutton.cpp" line="54" />
|
||||
<source>Erase-o</source>
|
||||
<source>Erase-o</source>
|
||||
<translation type="vanished">Supergum</translation>
|
||||
</message>
|
||||
<message>
|
||||
<translation>2000</translation>
|
||||
<location filename="../penbutton.cpp" line="55" />
|
||||
<source>matic 2000</source>
|
||||
<source>matic 2000</source>
|
||||
<translation type="vanished">2000</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<message>
|
||||
<location filename="../penbutton.cpp" line="54"/>
|
||||
<source>Erase-o</source>
|
||||
<comment>This and the next translation span two lines. Be spiffy with these!</comment>
|
||||
<translation type="unfinished">Supergum</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../penbutton.cpp" line="55"/>
|
||||
<source>matic 2000</source>
|
||||
<comment>This and the previous translation span two lines. Be spiffy with these!</comment>
|
||||
<translation type="unfinished">2000</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ScreenshotWindow</name>
|
||||
<message>
|
||||
<translation>SCHERMAFBEELDING</translation>
|
||||
<location filename="../screenshotwindow.ui" line="55" />
|
||||
<location filename="../../../../build-thedesk-Chroot_6-Debug/plugins/ScreenshotPlugin/plugin-screenshot_autogen/include/ui_screenshotwindow.h" line="192" />
|
||||
<source>SCREENSHOT</source>
|
||||
<location filename="../screenshotwindow.ui" line="55"/>
|
||||
<location filename="../../../../build-thedesk-Chroot_6-Debug/plugins/ScreenshotPlugin/plugin-screenshot_autogen/include/ui_screenshotwindow.h" line="192"/>
|
||||
<source>SCREENSHOT</source>
|
||||
<translation>SCHERMAFBEELDING</translation>
|
||||
</message>
|
||||
<message>
|
||||
<translation>Bijsnijden</translation>
|
||||
<location filename="../screenshotwindow.ui" line="130" />
|
||||
<location filename="../../../../build-thedesk-Chroot_6-Debug/plugins/ScreenshotPlugin/plugin-screenshot_autogen/include/ui_screenshotwindow.h" line="193" />
|
||||
<source>Crop</source>
|
||||
<location filename="../screenshotwindow.ui" line="130"/>
|
||||
<location filename="../../../../build-thedesk-Chroot_6-Debug/plugins/ScreenshotPlugin/plugin-screenshot_autogen/include/ui_screenshotwindow.h" line="193"/>
|
||||
<source>Crop</source>
|
||||
<translation>Bijsnijden</translation>
|
||||
</message>
|
||||
<message>
|
||||
<translation>Redigeren</translation>
|
||||
<location filename="../screenshotwindow.ui" line="150" />
|
||||
<location filename="../../../../build-thedesk-Chroot_6-Debug/plugins/ScreenshotPlugin/plugin-screenshot_autogen/include/ui_screenshotwindow.h" line="194" />
|
||||
<source>Redact</source>
|
||||
<location filename="../screenshotwindow.ui" line="150"/>
|
||||
<location filename="../../../../build-thedesk-Chroot_6-Debug/plugins/ScreenshotPlugin/plugin-screenshot_autogen/include/ui_screenshotwindow.h" line="194"/>
|
||||
<source>Redact</source>
|
||||
<translation>Redigeren</translation>
|
||||
</message>
|
||||
<message>
|
||||
<translation>Opmaak Herstellen</translation>
|
||||
<location filename="../screenshotwindow.ui" line="205" />
|
||||
<location filename="../../../../build-thedesk-Chroot_6-Debug/plugins/ScreenshotPlugin/plugin-screenshot_autogen/include/ui_screenshotwindow.h" line="195" />
|
||||
<source>Reset Markup</source>
|
||||
<location filename="../screenshotwindow.ui" line="205"/>
|
||||
<location filename="../../../../build-thedesk-Chroot_6-Debug/plugins/ScreenshotPlugin/plugin-screenshot_autogen/include/ui_screenshotwindow.h" line="195"/>
|
||||
<source>Reset Markup</source>
|
||||
<translation>Opmaak Herstellen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<translation>Verwijderen</translation>
|
||||
<location filename="../screenshotwindow.ui" line="216" />
|
||||
<location filename="../../../../build-thedesk-Chroot_6-Debug/plugins/ScreenshotPlugin/plugin-screenshot_autogen/include/ui_screenshotwindow.h" line="196" />
|
||||
<source>Discard</source>
|
||||
<location filename="../screenshotwindow.ui" line="216"/>
|
||||
<location filename="../../../../build-thedesk-Chroot_6-Debug/plugins/ScreenshotPlugin/plugin-screenshot_autogen/include/ui_screenshotwindow.h" line="196"/>
|
||||
<source>Discard</source>
|
||||
<translation>Verwijderen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<translation>Kopiëren</translation>
|
||||
<location filename="../screenshotwindow.ui" line="227" />
|
||||
<location filename="../../../../build-thedesk-Chroot_6-Debug/plugins/ScreenshotPlugin/plugin-screenshot_autogen/include/ui_screenshotwindow.h" line="197" />
|
||||
<source>Copy</source>
|
||||
<location filename="../screenshotwindow.ui" line="227"/>
|
||||
<location filename="../../../../build-thedesk-Chroot_6-Debug/plugins/ScreenshotPlugin/plugin-screenshot_autogen/include/ui_screenshotwindow.h" line="197"/>
|
||||
<source>Copy</source>
|
||||
<translation>Kopiëren</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
</context>
|
||||
</TS>
|
||||
|
|
Loading…
Reference in a new issue