- better UI
This commit is contained in:
parent
13e00590b1
commit
7cc4ce2b94
@ -1,14 +1,28 @@
|
|||||||
#include "connectdb_widget.h"
|
#include "connectdb_widget.h"
|
||||||
#include "ui_connectdb_widget.h"
|
#include "ui_connectdb_widget.h"
|
||||||
|
|
||||||
ConnectDbWidget::ConnectDbWidget(QWidget *parent) :
|
ConnectDbWidget::ConnectDbWidget(const QString& message, QWidget *parent) :
|
||||||
QWidget(parent),
|
QWidget(parent),
|
||||||
ui(new Ui::ConnectDbWidget)
|
ui(new Ui::ConnectDbWidget)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
ui->mMessageLabel->setText(message);
|
||||||
|
connect(ui->mButtonBox, SIGNAL(accepted()), this, SLOT(onOk()));
|
||||||
|
connect(ui->mButtonBox, SIGNAL(rejected()), this, SLOT(onCancel()));
|
||||||
|
connect(ui->mPasswordEdit, SIGNAL(returnPressed()), this, SLOT(onOk()));
|
||||||
}
|
}
|
||||||
|
|
||||||
ConnectDbWidget::~ConnectDbWidget()
|
ConnectDbWidget::~ConnectDbWidget()
|
||||||
{
|
{
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConnectDbWidget::onOk()
|
||||||
|
{
|
||||||
|
emit passwordEntered(ui->mPasswordEdit->text());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConnectDbWidget::onCancel()
|
||||||
|
{
|
||||||
|
emit cancelled();
|
||||||
|
}
|
||||||
|
|||||||
@ -12,11 +12,19 @@ class ConnectDbWidget : public QWidget
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ConnectDbWidget(QWidget *parent = nullptr);
|
explicit ConnectDbWidget(const QString& msg = QString(), QWidget *parent = nullptr);
|
||||||
~ConnectDbWidget();
|
~ConnectDbWidget();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::ConnectDbWidget *ui;
|
Ui::ConnectDbWidget *ui;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void onOk();
|
||||||
|
void onCancel();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void passwordEntered(const QString& password);
|
||||||
|
void cancelled();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CONNECTDB_WIDGET_H
|
#endif // CONNECTDB_WIDGET_H
|
||||||
|
|||||||
@ -10,10 +10,35 @@
|
|||||||
<height>114</height>
|
<height>114</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>200</width>
|
||||||
|
<height>100</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>400</width>
|
||||||
|
<height>150</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Form</string>
|
<string>Form</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="mMessageLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="textFormat">
|
||||||
|
<enum>Qt::PlainText</enum>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="mPasswordLabel">
|
<widget class="QLabel" name="mPasswordLabel">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@ -25,7 +50,14 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLineEdit" name="mPasswordEdit"/>
|
<widget class="QLineEdit" name="mPasswordEdit">
|
||||||
|
<property name="echoMode">
|
||||||
|
<enum>QLineEdit::Password</enum>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QDialogButtonBox" name="mButtonBox">
|
<widget class="QDialogButtonBox" name="mButtonBox">
|
||||||
|
|||||||
@ -26,13 +26,17 @@
|
|||||||
#include "finddialog.h"
|
#include "finddialog.h"
|
||||||
#include "startworkdialog.h"
|
#include "startworkdialog.h"
|
||||||
#include "stopworkdialog.h"
|
#include "stopworkdialog.h"
|
||||||
|
#include "connectdb_widget.h"
|
||||||
|
#include "openorcreatedb_widget.h"
|
||||||
|
|
||||||
#include <QDesktopWidget>
|
#include <QDesktopWidget>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#define SETTINGS mSettings->data()
|
#define SETTINGS mSettings->data()
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget *parent) :
|
MainWindow::MainWindow(QWidget *parent) :
|
||||||
QMainWindow(parent),
|
QMainWindow(parent),
|
||||||
ui(new Ui::MainWindow), mPasswordFailed(false), mFindInTasksDlg(this), mDockRecentMenu(nullptr)
|
mPasswordFailed(false), mFindInTasksDlg(this), mDockRecentMenu(nullptr)
|
||||||
{
|
{
|
||||||
mSettings = QSharedPointer<Settings>(new Settings());
|
mSettings = QSharedPointer<Settings>(new Settings());
|
||||||
|
|
||||||
@ -47,21 +51,30 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||||||
mCurrentIntervalLabel = nullptr;
|
mCurrentIntervalLabel = nullptr;
|
||||||
mTrayIcon = nullptr;
|
mTrayIcon = nullptr;
|
||||||
|
|
||||||
ui->setupUi(this);
|
|
||||||
|
|
||||||
// Hide Find line edit for now
|
|
||||||
ui->mFindFrame->setVisible(false);
|
|
||||||
helper::EscapeKeyEventFilter* eventFilter = new helper::EscapeKeyEventFilter(ui->mFindEdit);
|
|
||||||
connect(eventFilter, SIGNAL(escapePressed(QObject*)), this, SLOT(findRejected(QObject*)));
|
|
||||||
ui->mFindEdit->installEventFilter(eventFilter);
|
|
||||||
|
|
||||||
QCoreApplication::setApplicationName(APPNAME);
|
QCoreApplication::setApplicationName(APPNAME);
|
||||||
//QCoreApplication::setOrganizationName(COMPANY);
|
|
||||||
// Set this to your own appcast URL, of course
|
|
||||||
FvUpdater::sharedUpdater()->SetFeedURL("http://satorilight.com/LittAppCast.xml");
|
|
||||||
|
|
||||||
initClient();
|
loadGeometry();
|
||||||
QApplication::postEvent(this, new AttachDatabaseEvent());
|
|
||||||
|
// Now check if database is already configured
|
||||||
|
QWidget* centralWidget = new QWidget(this);
|
||||||
|
setCentralWidget(centralWidget);
|
||||||
|
centralWidget->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
|
||||||
|
|
||||||
|
// Check if database file exists
|
||||||
|
QString path = helper::path::pathToDatabase();
|
||||||
|
|
||||||
|
if (mSettings->data()[KEY_DB_FILENAME_SPECIFIED].toBool())
|
||||||
|
path = mSettings->data()[KEY_DB_FILENAME].toString();
|
||||||
|
|
||||||
|
QString folder = QFileInfo(path).absoluteDir().path();
|
||||||
|
Storage::instance().setPath(path);
|
||||||
|
|
||||||
|
if (!QFile::exists(path))
|
||||||
|
askNewDbPassword();
|
||||||
|
else
|
||||||
|
askDbPassword(QString());
|
||||||
|
|
||||||
|
this->setUpdatesEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow()
|
MainWindow::~MainWindow()
|
||||||
@ -75,12 +88,14 @@ void MainWindow::attachDatabase()
|
|||||||
{
|
{
|
||||||
// Open database
|
// Open database
|
||||||
QString path = helper::path::pathToDatabase();
|
QString path = helper::path::pathToDatabase();
|
||||||
|
|
||||||
if (mSettings->data()[KEY_DB_FILENAME_SPECIFIED].toBool())
|
if (mSettings->data()[KEY_DB_FILENAME_SPECIFIED].toBool())
|
||||||
path = mSettings->data()[KEY_DB_FILENAME].toString();
|
path = mSettings->data()[KEY_DB_FILENAME].toString();
|
||||||
|
|
||||||
QString folder = QFileInfo(path).absoluteDir().path();
|
QString folder = QFileInfo(path).absoluteDir().path();
|
||||||
Storage::instance().setPath(path);
|
Storage::instance().setPath(path);
|
||||||
|
|
||||||
|
/*
|
||||||
if (!QFile::exists(path))
|
if (!QFile::exists(path))
|
||||||
{
|
{
|
||||||
QDir().mkpath(folder);
|
QDir().mkpath(folder);
|
||||||
@ -93,7 +108,6 @@ void MainWindow::attachDatabase()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// See if there is stored password
|
// See if there is stored password
|
||||||
QString password;
|
|
||||||
if (mSettings->data()[KEY_AUTOSAVE_PASSWORD].toBool() && mSettings->data()[KEY_PASSWORD].toString() != NOPASSWORDSTRING)
|
if (mSettings->data()[KEY_AUTOSAVE_PASSWORD].toBool() && mSettings->data()[KEY_PASSWORD].toString() != NOPASSWORDSTRING)
|
||||||
password = mSettings->data()[KEY_PASSWORD].toString();
|
password = mSettings->data()[KEY_PASSWORD].toString();
|
||||||
else
|
else
|
||||||
@ -102,26 +116,10 @@ void MainWindow::attachDatabase()
|
|||||||
connect(mPasswordDlg, SIGNAL(finished(int)), this, SLOT(passwordDialogFinished(int)));
|
connect(mPasswordDlg, SIGNAL(finished(int)), this, SLOT(passwordDialogFinished(int)));
|
||||||
mPasswordDlg->show();
|
mPasswordDlg->show();
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
this->setUpdatesEnabled(true);
|
this->setUpdatesEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::openDatabase(const QString &password)
|
|
||||||
{
|
|
||||||
Storage::instance().setKey(password);
|
|
||||||
if (!Storage::instance().open())
|
|
||||||
{
|
|
||||||
mPasswordFailed = true;
|
|
||||||
alertBox(tr("Error"), tr("Failed to open database"), AlertType_CannotOpen);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (mSettings->data()[KEY_AUTOSAVE_PASSWORD].toBool())
|
|
||||||
{
|
|
||||||
mSettings->data()[KEY_PASSWORD] = password;
|
|
||||||
mSettings->save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::connectUiToDatabase()
|
void MainWindow::connectUiToDatabase()
|
||||||
{
|
{
|
||||||
ui->mTaskTree->setModel(mTaskTreeModel = new TaskTreeModel(false));
|
ui->mTaskTree->setModel(mTaskTreeModel = new TaskTreeModel(false));
|
||||||
@ -172,10 +170,6 @@ void MainWindow::alertBox(const QString &title, const QString &text, AlertType a
|
|||||||
connect(mAlertBox, SIGNAL(finished(int)), this, SLOT(criticalAlertFinished(int)));
|
connect(mAlertBox, SIGNAL(finished(int)), this, SLOT(criticalAlertFinished(int)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AlertType_CannotOpen:
|
|
||||||
connect(mAlertBox, SIGNAL(finished(int)), this, SLOT(openAlertFinished(int)));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AlertType_Warning:
|
case AlertType_Warning:
|
||||||
connect(mAlertBox, SIGNAL(finished(int)), this, SLOT(warningAlertFinished(int)));
|
connect(mAlertBox, SIGNAL(finished(int)), this, SLOT(warningAlertFinished(int)));
|
||||||
break;
|
break;
|
||||||
@ -293,7 +287,7 @@ void MainWindow::save()
|
|||||||
|
|
||||||
QSharedPointer<QByteArray> MainWindow::getUndoStack() const
|
QSharedPointer<QByteArray> MainWindow::getUndoStack() const
|
||||||
{
|
{
|
||||||
QTextDocument* doc = ui->mNoteEdit->document();
|
//QTextDocument* doc = ui->mNoteEdit->document();
|
||||||
|
|
||||||
return QSharedPointer<QByteArray>(new QByteArray());
|
return QSharedPointer<QByteArray>(new QByteArray());
|
||||||
}
|
}
|
||||||
@ -356,7 +350,7 @@ void MainWindow::loadGeometry()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set splitter position
|
// Set splitter position
|
||||||
if (settings.contains(KEY_SPLITTEROFFSET1) && settings.contains(KEY_SPLITTEROFFSET2))
|
if (settings.contains(KEY_SPLITTEROFFSET1) && settings.contains(KEY_SPLITTEROFFSET2) && ui)
|
||||||
{
|
{
|
||||||
QList<int> sizes = ui->mSplitter->sizes();
|
QList<int> sizes = ui->mSplitter->sizes();
|
||||||
sizes[0] = settings.value(KEY_SPLITTEROFFSET1).toInt();
|
sizes[0] = settings.value(KEY_SPLITTEROFFSET1).toInt();
|
||||||
@ -364,7 +358,7 @@ void MainWindow::loadGeometry()
|
|||||||
ui->mSplitter->setSizes(sizes);
|
ui->mSplitter->setSizes(sizes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.contains(KEY_TIMESPLITTER_OFFSET1) && settings.contains(KEY_TIMESPLITTER_OFFSET2))
|
if (settings.contains(KEY_TIMESPLITTER_OFFSET1) && settings.contains(KEY_TIMESPLITTER_OFFSET2) && ui)
|
||||||
{
|
{
|
||||||
QList<int> sizes = ui->mTimeSplitter->sizes();
|
QList<int> sizes = ui->mTimeSplitter->sizes();
|
||||||
sizes[0] = settings.value(KEY_TIMESPLITTER_OFFSET1).toInt();
|
sizes[0] = settings.value(KEY_TIMESPLITTER_OFFSET1).toInt();
|
||||||
@ -380,22 +374,24 @@ void MainWindow::sync()
|
|||||||
|
|
||||||
void MainWindow::closeEvent(QCloseEvent * ev)
|
void MainWindow::closeEvent(QCloseEvent * ev)
|
||||||
{
|
{
|
||||||
// Update DB if document was modified
|
if (ui)
|
||||||
if (ui->mNoteEdit->document()->isModified())
|
|
||||||
{
|
{
|
||||||
// See if there is active selection
|
// Update DB if document was modified
|
||||||
QModelIndex index = ui->mTaskTree->currentIndex();
|
if (ui->mNoteEdit->document()->isModified())
|
||||||
if (index.isValid())
|
|
||||||
{
|
{
|
||||||
PTask task = mTaskTreeModel->getTask(index);
|
// See if there is active selection
|
||||||
task->setHtml(ui->mNoteEdit->document()->toPlainText());
|
QModelIndex index = ui->mTaskTree->currentIndex();
|
||||||
task->save();
|
if (index.isValid())
|
||||||
|
{
|
||||||
|
PTask task = mTaskTreeModel->getTask(index);
|
||||||
|
task->setHtml(ui->mNoteEdit->document()->toPlainText());
|
||||||
|
task->save();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!mPasswordFailed)
|
||||||
|
save();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mPasswordFailed)
|
|
||||||
save();
|
|
||||||
|
|
||||||
ev->accept();
|
ev->accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -804,6 +800,56 @@ void MainWindow::updateAttachmentsLabel(PTask t)
|
|||||||
mAttachmentsLabel->setText(text);
|
mAttachmentsLabel->setText(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::setupMainUi()
|
||||||
|
{
|
||||||
|
// Detach old widget
|
||||||
|
setCentralWidget(nullptr);
|
||||||
|
|
||||||
|
// Construct main UI
|
||||||
|
ui = new Ui::MainWindow();
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
// Hide Find line edit for now
|
||||||
|
ui->mFindFrame->setVisible(false);
|
||||||
|
helper::EscapeKeyEventFilter* eventFilter = new helper::EscapeKeyEventFilter(ui->mFindEdit);
|
||||||
|
connect(eventFilter, SIGNAL(escapePressed(QObject*)), this, SLOT(findRejected(QObject*)));
|
||||||
|
ui->mFindEdit->installEventFilter(eventFilter);
|
||||||
|
|
||||||
|
//QCoreApplication::setOrganizationName(COMPANY);
|
||||||
|
// Set this to your own appcast URL, of course
|
||||||
|
FvUpdater::sharedUpdater()->SetFeedURL("http://satorilight.com/LittAppCast.xml");
|
||||||
|
|
||||||
|
initClient();
|
||||||
|
QApplication::postEvent(this, new AttachDatabaseEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ask password
|
||||||
|
void MainWindow::askDbPassword(const QString& message)
|
||||||
|
{
|
||||||
|
setCentralWidget(nullptr); setCentralWidget(new QWidget(this));
|
||||||
|
auto cdw = new ConnectDbWidget(message, centralWidget());
|
||||||
|
connect(cdw, SIGNAL(passwordEntered(QString)), this, SLOT(onDbPasswordEntered(QString)));
|
||||||
|
connect(cdw, SIGNAL(cancelled()), this, SLOT(onDbPasswordCancelled()));
|
||||||
|
|
||||||
|
QVBoxLayout* l = new QVBoxLayout(centralWidget());
|
||||||
|
l->addWidget(cdw);
|
||||||
|
l->setAlignment(Qt::AlignCenter);
|
||||||
|
centralWidget()->setLayout(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::askNewDbPassword()
|
||||||
|
{
|
||||||
|
setCentralWidget(nullptr); setCentralWidget(new QWidget(this));
|
||||||
|
auto w = new OpenOrCreateDbWidget(centralWidget());
|
||||||
|
connect(w, &OpenOrCreateDbWidget::databaseChanged, [this](const QString& path) { onDatabaseChanged(path); });
|
||||||
|
connect(w, &OpenOrCreateDbWidget::passwordEntered, [this](const QString& password) { onNewDbPasswordEntered(password); });
|
||||||
|
|
||||||
|
auto l = new QVBoxLayout(centralWidget());
|
||||||
|
l->addWidget(w);
|
||||||
|
l->setAlignment(Qt::AlignCenter);
|
||||||
|
centralWidget()->setLayout(l);
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::startOrStopTracking()
|
void MainWindow::startOrStopTracking()
|
||||||
{
|
{
|
||||||
if (!mCurrentTask)
|
if (!mCurrentTask)
|
||||||
@ -1351,61 +1397,12 @@ void MainWindow::showTimeReport()
|
|||||||
trz.exec();
|
trz.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::newPasswordDialogFinished(int status)
|
|
||||||
{
|
|
||||||
if (status == QDialog::Accepted)
|
|
||||||
{
|
|
||||||
Storage::instance().setKey(mNewPasswordDlg->password());
|
|
||||||
if (!Storage::instance().create())
|
|
||||||
{
|
|
||||||
// Quit application
|
|
||||||
mPasswordFailed = true;
|
|
||||||
alertBox(tr("Error"), tr("Failed to initialize database"), AlertType_Critical);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remember password if it is specified in settings
|
|
||||||
if (mSettings->data()[KEY_AUTOSAVE_PASSWORD].toBool())
|
|
||||||
mSettings->data()[KEY_PASSWORD] = mNewPasswordDlg->password();
|
|
||||||
else
|
|
||||||
mSettings->data()[KEY_PASSWORD] = NOPASSWORDSTRING;
|
|
||||||
|
|
||||||
// Flush settings
|
|
||||||
mSettings->save();
|
|
||||||
|
|
||||||
connectUiToDatabase();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::passwordDialogFinished(int status)
|
|
||||||
{
|
|
||||||
QString password;
|
|
||||||
if (status == QDialog::Accepted)
|
|
||||||
{
|
|
||||||
password = mPasswordDlg->password();
|
|
||||||
openDatabase(password);
|
|
||||||
connectUiToDatabase();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mPasswordFailed = false;
|
|
||||||
QApplication::postEvent(this, new ClientCloseEvent());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::criticalAlertFinished(int /*status*/)
|
void MainWindow::criticalAlertFinished(int /*status*/)
|
||||||
{
|
{
|
||||||
QApplication::postEvent(this, new ClientCloseEvent());
|
QApplication::postEvent(this, new ClientCloseEvent());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::openAlertFinished(int /*status*/)
|
|
||||||
{
|
|
||||||
mPasswordDlg = new PasswordDlg(this);
|
|
||||||
connect(mPasswordDlg, SIGNAL(finished(int)), this, SLOT(passwordDialogFinished(int)));
|
|
||||||
mPasswordDlg->show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::warningAlertFinished(int /*status*/)
|
void MainWindow::warningAlertFinished(int /*status*/)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -1618,3 +1615,72 @@ void MainWindow::trayWindowDestroyed(QObject *object)
|
|||||||
{
|
{
|
||||||
mTrayWindow = nullptr;
|
mTrayWindow = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::onDbPasswordEntered(const QString& password)
|
||||||
|
{
|
||||||
|
if (mSettings->data()[KEY_AUTOSAVE_PASSWORD].toBool())
|
||||||
|
{
|
||||||
|
mSettings->data()[KEY_PASSWORD] = password;
|
||||||
|
mSettings->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
Storage::instance().setKey(password);
|
||||||
|
if (!Storage::instance().open())
|
||||||
|
{
|
||||||
|
askDbPassword(tr("Invalid password, please try again."));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setupMainUi();
|
||||||
|
connectUiToDatabase();
|
||||||
|
loadGeometry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::onDbPasswordCancelled()
|
||||||
|
{
|
||||||
|
askNewDbPassword();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::onNewDbPasswordEntered(const QString& password)
|
||||||
|
{
|
||||||
|
if (mSettings->data()[KEY_AUTOSAVE_PASSWORD].toBool())
|
||||||
|
{
|
||||||
|
mSettings->data()[KEY_PASSWORD] = password;
|
||||||
|
mSettings->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
Storage::instance().setKey(password);
|
||||||
|
|
||||||
|
// Remove old database
|
||||||
|
::remove(Storage::instance().path().toStdString().c_str());
|
||||||
|
|
||||||
|
// Try to create new one
|
||||||
|
if (!Storage::instance().create())
|
||||||
|
{
|
||||||
|
showFatal(tr("Failed to create new database. Exiting."));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setupMainUi();
|
||||||
|
connectUiToDatabase();
|
||||||
|
loadGeometry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::onDatabaseChanged(const QString& path)
|
||||||
|
{
|
||||||
|
// Bind to specific database
|
||||||
|
mSettings->data()[KEY_DB_FILENAME_SPECIFIED] = true;
|
||||||
|
mSettings->data()[KEY_DB_FILENAME] = path;
|
||||||
|
mSettings->save();
|
||||||
|
Storage::instance().setPath(path);
|
||||||
|
|
||||||
|
askDbPassword();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::showFatal(const QString& message)
|
||||||
|
{
|
||||||
|
std::cerr << message.toStdString() << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|||||||
@ -28,185 +28,201 @@ class MainWindow;
|
|||||||
|
|
||||||
class MainWindow : public QMainWindow
|
class MainWindow : public QMainWindow
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MainWindow(QWidget *parent = 0);
|
explicit MainWindow(QWidget *parent = nullptr);
|
||||||
~MainWindow();
|
~MainWindow();
|
||||||
protected:
|
protected:
|
||||||
void closeEvent(QCloseEvent *);
|
void closeEvent(QCloseEvent *);
|
||||||
void customEvent(QEvent *);
|
void customEvent(QEvent *);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum TrackingStopReason
|
enum TrackingStopReason
|
||||||
{
|
{
|
||||||
TSR_None, // Used to init only
|
TSR_None, // Used to init only
|
||||||
TSR_Manual,
|
TSR_Manual,
|
||||||
TSR_Automatic
|
TSR_Automatic
|
||||||
};
|
};
|
||||||
|
|
||||||
QSharedPointer<Logger> mLogger;
|
QSharedPointer<Logger> mLogger;
|
||||||
QSharedPointer<HIDActivityTracker> mActivityTracker;
|
QSharedPointer<HIDActivityTracker> mActivityTracker;
|
||||||
TrackingStopReason mStopReason;
|
TrackingStopReason mStopReason;
|
||||||
|
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui = nullptr;
|
||||||
TaskTreeModel* mTaskTreeModel;
|
TaskTreeModel* mTaskTreeModel;
|
||||||
PTask mCurrentTask, mAutomaticTask;
|
PTask mCurrentTask, mAutomaticTask;
|
||||||
QTimer* mUpdateTimer;
|
QTimer* mUpdateTimer;
|
||||||
QLabel* mModifiedLabel;
|
QLabel* mModifiedLabel;
|
||||||
QLabel* mCurrentIntervalLabel;
|
QLabel* mCurrentIntervalLabel;
|
||||||
QLabel* mDuplicationSignalLabel;
|
QLabel* mDuplicationSignalLabel;
|
||||||
QSystemTrayIcon *mTrayIcon;
|
QSystemTrayIcon *mTrayIcon;
|
||||||
QSharedPointer<Settings> mSettings;
|
QSharedPointer<Settings> mSettings;
|
||||||
bool mPasswordFailed;
|
bool mPasswordFailed;
|
||||||
PasswordDlg* mPasswordDlg;
|
PasswordDlg* mPasswordDlg;
|
||||||
NewPasswordDlg* mNewPasswordDlg;
|
NewPasswordDlg* mNewPasswordDlg;
|
||||||
QMessageBox* mAlertBox;
|
QMessageBox* mAlertBox;
|
||||||
|
|
||||||
// Time when current note was saved to DB last time
|
// Time when current note was saved to DB last time
|
||||||
QDateTime mLastTimelineFlush;
|
QDateTime mLastTimelineFlush;
|
||||||
|
|
||||||
// Attachments action
|
// Attachments action
|
||||||
QAction* mAttachmentsAction;
|
QAction* mAttachmentsAction;
|
||||||
|
|
||||||
// Attachments label
|
// Attachments label
|
||||||
QLabel* mAttachmentsLabel;
|
QLabel* mAttachmentsLabel;
|
||||||
|
|
||||||
// Delegate to draw task items in custom way
|
// Delegate to draw task items in custom way
|
||||||
TaskItemDelegate mTaskItemDelegate;
|
TaskItemDelegate mTaskItemDelegate;
|
||||||
|
|
||||||
// Find text in document start index
|
// Find text in document start index
|
||||||
int mFindStartIndex;
|
int mFindStartIndex;
|
||||||
QString mFindPattern;
|
QString mFindPattern;
|
||||||
FindInTasksDialog mFindInTasksDlg;
|
FindInTasksDialog mFindInTasksDlg;
|
||||||
|
|
||||||
#ifdef TARGET_OSX
|
#ifdef TARGET_OSX
|
||||||
SleepTracker mSleepTracker;
|
SleepTracker mSleepTracker;
|
||||||
#endif
|
#endif
|
||||||
QSharedPointer<QByteArray> getUndoStack() const;
|
QSharedPointer<QByteArray> getUndoStack() const;
|
||||||
int mTimeFrameHeight;
|
int mTimeFrameHeight;
|
||||||
|
|
||||||
QDateTime mTextModificationTime;
|
QDateTime mTextModificationTime;
|
||||||
std::deque<PTask> mRecentTrackingTasks;
|
std::deque<PTask> mRecentTrackingTasks;
|
||||||
QMenu* mDockRecentMenu;
|
QMenu* mDockRecentMenu;
|
||||||
QDialog* mTrayWindow = nullptr;
|
QDialog* mTrayWindow = nullptr;
|
||||||
|
QString mPassword = NOPASSWORDSTRING;
|
||||||
|
|
||||||
void saveGeometry();
|
|
||||||
void loadGeometry();
|
|
||||||
void applyTextFormat(const QTextCharFormat& fmt);
|
|
||||||
void initClient();
|
|
||||||
|
|
||||||
// Checks if database exists, requests passwords etc.
|
void saveGeometry();
|
||||||
void attachDatabase();
|
void loadGeometry();
|
||||||
|
void applyTextFormat(const QTextCharFormat& fmt);
|
||||||
|
void initClient();
|
||||||
|
|
||||||
// Just open database via Storage::instance()
|
// Checks if database exists, requests passwords etc.
|
||||||
void openDatabase(const QString& password);
|
void attachDatabase();
|
||||||
|
|
||||||
// Creates task tree model, adjusts UI
|
// Just open database via Storage::instance()
|
||||||
void connectUiToDatabase();
|
void openDatabase(const QString& password);
|
||||||
|
|
||||||
// Shows window with alert text and button OK
|
// Creates task tree model, adjusts UI
|
||||||
enum AlertType
|
void connectUiToDatabase();
|
||||||
{
|
|
||||||
AlertType_Warning,
|
|
||||||
AlertType_Critical,
|
|
||||||
AlertType_CannotOpen
|
|
||||||
};
|
|
||||||
|
|
||||||
void alertBox(const QString& title, const QString& text, AlertType alertType);
|
// Shows window with alert text and button OK
|
||||||
|
enum AlertType
|
||||||
|
{
|
||||||
|
AlertType_Warning,
|
||||||
|
AlertType_Critical,
|
||||||
|
AlertType_CannotOpen
|
||||||
|
};
|
||||||
|
|
||||||
void showTimeForSelectedTask();
|
void alertBox(const QString& title, const QString& text, AlertType alertType);
|
||||||
void showTimeForTrackingTask();
|
|
||||||
void initTrayIcon();
|
|
||||||
void removeTrayIcon();
|
|
||||||
|
|
||||||
enum TrayShowMessage
|
void showTimeForSelectedTask();
|
||||||
{
|
void showTimeForTrackingTask();
|
||||||
Tray_ShowMessage = 0,
|
void initTrayIcon();
|
||||||
Tray_SkipMessage = 1
|
void removeTrayIcon();
|
||||||
};
|
|
||||||
void updateTrayIcon(TrayShowMessage flag);
|
enum TrayShowMessage
|
||||||
void handleTrackableState(PTask task);
|
{
|
||||||
void trayContextualMenu();
|
Tray_ShowMessage = 0,
|
||||||
int showTrayWindow(QDialog* dlg);
|
Tray_SkipMessage = 1
|
||||||
void installDockMenu();
|
};
|
||||||
void startTracking(PTask t);
|
void updateTrayIcon(TrayShowMessage flag);
|
||||||
void prepareRecentTasksMenu(QMenu* submenu);
|
void handleTrackableState(PTask task);
|
||||||
void updateAttachmentsLabel(PTask t);
|
void trayContextualMenu();
|
||||||
|
int showTrayWindow(QDialog* dlg);
|
||||||
|
void installDockMenu();
|
||||||
|
void startTracking(PTask t);
|
||||||
|
void prepareRecentTasksMenu(QMenu* submenu);
|
||||||
|
void updateAttachmentsLabel(PTask t);
|
||||||
|
|
||||||
|
// Builds main UI layut
|
||||||
|
void setupMainUi();
|
||||||
|
|
||||||
|
// Show UI to ask password for existing DB
|
||||||
|
void askDbPassword(const QString& message = QString(""));
|
||||||
|
|
||||||
|
// Show UI to ask password for new database (or select existing database file)
|
||||||
|
void askNewDbPassword();
|
||||||
|
|
||||||
|
// Show UI about fatal alert & button to quit app
|
||||||
|
void showFatal(const QString& message);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void onTimeFormatChanged();
|
void onTimeFormatChanged();
|
||||||
void onTimeChanged();
|
void onTimeChanged();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void save();
|
void save();
|
||||||
void sync();
|
void sync();
|
||||||
void about();
|
void about();
|
||||||
void preferences();
|
void preferences();
|
||||||
void print();
|
void print();
|
||||||
void quit();
|
void quit();
|
||||||
void newRootTask();
|
void newRootTask();
|
||||||
void newTask();
|
void newTask();
|
||||||
void newSibling();
|
void newSibling();
|
||||||
void moveUp();
|
void moveUp();
|
||||||
void moveDown();
|
void moveDown();
|
||||||
void renameTask();
|
void renameTask();
|
||||||
void deleteTask();
|
void deleteTask();
|
||||||
void taskTreeContextualMenu(const QPoint& point);
|
void taskTreeContextualMenu(const QPoint& point);
|
||||||
void taskIndexChanged(const QModelIndex&, const QModelIndex&);
|
void taskIndexChanged(const QModelIndex&, const QModelIndex&);
|
||||||
void idleDetected();
|
void idleDetected();
|
||||||
void activityDetected();
|
void activityDetected();
|
||||||
void startOrStopTracking();
|
void startOrStopTracking();
|
||||||
void startTracking();
|
void startTracking();
|
||||||
void startTrackingRecent();
|
void startTrackingRecent();
|
||||||
|
|
||||||
void stopTracking(TrackingStopReason reason, time_t current_utc = time(nullptr));
|
void stopTracking(TrackingStopReason reason, time_t current_utc = time(nullptr));
|
||||||
void updateData();
|
void updateData();
|
||||||
void add10Mins();
|
void add10Mins();
|
||||||
|
|
||||||
void editSelectionChanged();
|
void editSelectionChanged();
|
||||||
void editPositionChanged();
|
void editPositionChanged();
|
||||||
void editFormatChanged(const QTextCharFormat& fmt);
|
void editFormatChanged(const QTextCharFormat& fmt);
|
||||||
|
|
||||||
void editUndo();
|
void editUndo();
|
||||||
void editRedo();
|
void editRedo();
|
||||||
void editCut();
|
void editCut();
|
||||||
void editCopy();
|
void editCopy();
|
||||||
void editPaste();
|
void editPaste();
|
||||||
void editDelete();
|
void editDelete();
|
||||||
void editSelectAll();
|
void editSelectAll();
|
||||||
|
|
||||||
void iconActivated(QSystemTrayIcon::ActivationReason reason);
|
void iconActivated(QSystemTrayIcon::ActivationReason reason);
|
||||||
void timeFormatChanged();
|
void timeFormatChanged();
|
||||||
void showTimeline();
|
void showTimeline();
|
||||||
void showTimeReport();
|
void showTimeReport();
|
||||||
|
|
||||||
void newPasswordDialogFinished(int status);
|
void criticalAlertFinished(int status);
|
||||||
void passwordDialogFinished(int status);
|
void warningAlertFinished(int status);
|
||||||
void criticalAlertFinished(int status);
|
void toolbarVisibilityChanged(bool visible);
|
||||||
void openAlertFinished(int status);
|
void showHideToolbar();
|
||||||
void warningAlertFinished(int status);
|
void showAttachments();
|
||||||
void toolbarVisibilityChanged(bool visible);
|
void checkForUpdates();
|
||||||
void showHideToolbar();
|
void systemSleep();
|
||||||
void showAttachments();
|
void systemResume();
|
||||||
void checkForUpdates();
|
void changeTimeTrackableFlag(bool trackable);
|
||||||
void systemSleep();
|
void find();
|
||||||
void systemResume();
|
void findInTasks();
|
||||||
void changeTimeTrackableFlag(bool trackable);
|
void findRequested();
|
||||||
void find();
|
void findRejected(QObject* obj);
|
||||||
void findInTasks();
|
void taskTextChanged();
|
||||||
void findRequested();
|
void taskMoved(PTask task);
|
||||||
void findRejected(QObject* obj);
|
void focusTaskTree();
|
||||||
void taskTextChanged();
|
void focusTaskText();
|
||||||
void taskMoved(PTask task);
|
void showMainWindow();
|
||||||
void focusTaskTree();
|
void continueOnIdle();
|
||||||
void focusTaskText();
|
void breakOnIdle(const QDateTime& stopTime);
|
||||||
void showMainWindow();
|
void startOnActivity();
|
||||||
void continueOnIdle();
|
void stopOnActivity();
|
||||||
void breakOnIdle(const QDateTime& stopTime);
|
void trayWindowDestroyed(QObject* object);
|
||||||
void startOnActivity();
|
|
||||||
void stopOnActivity();
|
void onDbPasswordEntered(const QString& password);
|
||||||
void trayWindowDestroyed(QObject* object);
|
void onDbPasswordCancelled();
|
||||||
|
void onNewDbPasswordEntered(const QString& password);
|
||||||
|
void onDatabaseChanged(const QString& path);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MAINWINDOW_H
|
#endif // MAINWINDOW_H
|
||||||
|
|||||||
@ -1,14 +1,55 @@
|
|||||||
#include "openorcreatedb_widget.h"
|
#include "openorcreatedb_widget.h"
|
||||||
#include "ui_openorcreatedb_widget.h"
|
#include "ui_openorcreatedb_widget.h"
|
||||||
|
|
||||||
|
#include <QFileDialog>
|
||||||
|
|
||||||
OpenOrCreateDbWidget::OpenOrCreateDbWidget(QWidget *parent) :
|
OpenOrCreateDbWidget::OpenOrCreateDbWidget(QWidget *parent) :
|
||||||
QWidget(parent),
|
QWidget(parent),
|
||||||
ui(new Ui::OpenOrCreateDbWidget)
|
ui(new Ui::OpenOrCreateDbWidget)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
connect(ui->mNewPasswordEdit1, &QLineEdit::returnPressed, [this]() { ui->mNewPasswordEdit2->setFocus(); });
|
||||||
|
connect(ui->mNewPasswordEdit2, &QLineEdit::returnPressed, [this]() { handleEnteredPasswords(); });
|
||||||
|
connect(ui->mSelectDatabaseButton, &QPushButton::clicked, [this]() { askForDatabase(); });
|
||||||
|
connect(ui->mDialogButtonBox, &QDialogButtonBox::accepted, [this]()
|
||||||
|
{
|
||||||
|
if (mDbPath.isEmpty())
|
||||||
|
handleEnteredPasswords();
|
||||||
|
else
|
||||||
|
emit databaseChanged(ui->mSelectedDbLabel->text());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenOrCreateDbWidget::~OpenOrCreateDbWidget()
|
OpenOrCreateDbWidget::~OpenOrCreateDbWidget()
|
||||||
{
|
{
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenOrCreateDbWidget::handleEnteredPasswords()
|
||||||
|
{
|
||||||
|
if (ui->mNewPasswordEdit1->text().isEmpty() && ui->mNewPasswordEdit2->text().isEmpty())
|
||||||
|
{
|
||||||
|
ui->mMessageLabel->setText("Password can't be empty. Please try again!");
|
||||||
|
}
|
||||||
|
if (ui->mNewPasswordEdit1->text() == ui->mNewPasswordEdit2->text())
|
||||||
|
emit passwordEntered(ui->mNewPasswordEdit1->text());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ui->mNewPasswordEdit1->setText("");
|
||||||
|
ui->mNewPasswordEdit2->setText("");
|
||||||
|
ui->mNewPasswordEdit1->setFocus();
|
||||||
|
ui->mMessageLabel->setText("Passwords are not the same. Please try again!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenOrCreateDbWidget::askForDatabase()
|
||||||
|
{
|
||||||
|
QString path = QFileDialog::getOpenFileName(this, "Please select existing database", QString(), "*.litt");
|
||||||
|
if (path.size())
|
||||||
|
{
|
||||||
|
mDbPath = path;
|
||||||
|
ui->mSelectedDbLabel->setText(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,6 +17,14 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::OpenOrCreateDbWidget *ui;
|
Ui::OpenOrCreateDbWidget *ui;
|
||||||
|
|
||||||
|
QString mDbPath;
|
||||||
|
void handleEnteredPasswords();
|
||||||
|
void askForDatabase();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void databaseChanged(const QString& path);
|
||||||
|
void passwordEntered(const QString& password);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // OPENORCREATEDB_WIDGET_H
|
#endif // OPENORCREATEDB_WIDGET_H
|
||||||
|
|||||||
@ -6,10 +6,22 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>549</width>
|
<width>400</width>
|
||||||
<height>384</height>
|
<height>300</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>400</width>
|
||||||
|
<height>300</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>400</width>
|
||||||
|
<height>400</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Form</string>
|
<string>Form</string>
|
||||||
</property>
|
</property>
|
||||||
@ -59,6 +71,16 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="mMessageLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QLabel" name="label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@ -106,7 +128,7 @@
|
|||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="standardButtons">
|
<property name="standardButtons">
|
||||||
<set>QDialogButtonBox::Ok</set>
|
<set>QDialogButtonBox::Ok|QDialogButtonBox::Reset</set>
|
||||||
</property>
|
</property>
|
||||||
<property name="centerButtons">
|
<property name="centerButtons">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user