notes(筆記軟體)
樣式表
QWidget {
font: 14px "Roboto";
color: rgb(26, 26, 26);
background-color: rgb(255, 255, 255);
}
QTextBrowser {
font: 14px "Arimo";
color: rgb(117, 117, 117);
border:
1px
solid
rgb(205
background-color: rgb(255, 255, 252);
}
QProgressBar {
height: 24px;
font-weight: 500;
border-radius: 5px;
border: 1px solid rgb(205, 205, 205);
background-color:
rgb(251, 251, 251);
}
QProgressBar::chunk {
border-radius: 5px;
background-color: rgb(65, 154, 223);
}
QPushButton {
font-size: 15px;
font-weight: 500;
border-width: 0px;
color: rgb(68, 138, 201);
}
QPushButton:!enabled
{
color: rgb(132, 132, 132);
}
QPushButton:hover:!pressed {
color: rgb(51, 110, 162);
}
QPushButton:pressed {
color: rgb(39, 85, 125);
border: 1px solid rgb(170, 170, 170);
border-radius: 5px;
}
#timeLabel {
font: 13px "Roboto";
}
#title {
font: 500 25px "Roboto";
}
#whatsNewLabel, #downloadLabel {
font: 500 14px "Roboto";
}
**為列表設定代理
為表格設定代理
void NoteWidgetDelegate::paintBackground(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if((option.state & QStyle::State_Selected) == QStyle::State_Selected){
if(qApp->applicationState() == Qt::ApplicationActive){
if(m_isActive){
painter->fillRect(option.rect, QBrush(m_ActiveColor));
}else{
painter->fillRect(option.rect, QBrush(m_notActiveColor));
}
}else if(qApp->applicationState() == Qt::ApplicationInactive){
painter->fillRect(option.rect, QBrush(m_applicationInactiveColor));
}
}else if((option.state & QStyle::State_MouseOver) == QStyle::State_MouseOver){
painter->fillRect(option.rect, QBrush(m_hoverColor));
}else if((index.row() != m_currentSelectedIndex.row() - 1)
&& (index.row() != m_hoveredIndex.row() - 1)){
painter->fillRect(option.rect, QBrush(m_defaultColor));
paintSeparator(painter, option, index);
}
}
T
**單例模式(只允許開啟一個例項)
/*********************************************************************************************
*
Mozila
License
*
Just
a
meantime
project
to
see
the
ability
of
qt,
the
framework
that
my
OS
might
be
based
on
*
And
for
those
linux
users
that
beleive
in
the
power
of
notes
*********************************************************************************************/
#include
"mainwindow.h"
#include
"singleinstance.h"
#include
<QApplication>
#include
<QFontDatabase>
int
main(int
argc,
char
*argv[])
{
QApplication::setDesktopSettingsAware(false);
QApplication
app
(argc,
argv);
//
Set
application
information
app.setApplicationName
("Notes");
app.setApplicationVersion
("1.5.0");
//
Load
fonts
from
resources
QFontDatabase::addApplicationFont
(":/fonts/arimo/Arimo-Regular.ttf");
QFontDatabase::addApplicationFont
(":/fonts/roboto-hinted/Roboto-Bold.ttf");
QFontDatabase::addApplicationFont
(":/fonts/roboto-hinted/Roboto-Medium.ttf");
QFontDatabase::addApplicationFont (":/fonts/roboto-hinted/Roboto-Regular.ttf");
//
Prevent
many
instances
of
the
app
to
be
launched
QString
name
=
"com.awsomeness.notes";
SingleInstance
instance;
if
(instance.hasPrevious (name)){
return
EXIT_SUCCESS;
}
instance.listen
(name);
//
Create
and
Show
the
app
MainWindow
w;
w.show();
//
Bring
the
Notes
window
to
the
front
QObject::connect(&instance,
&SingleInstance::newInstance,
[&](){
(&w)->setMainWindowVisibility(true);
});
return
app.exec();
}
程式下載介面
+程式下載更新 json檔案中有下載連結
+下載安裝包,刪除以前的檔案
void UpdaterWindow::startDownload(const QUrl& url)
{
/* URL is invalid, try opening web browser */
if(url.isEmpty()){
QDesktopServices::openUrl(QUrl(m_updater->getOpenUrl(UPDATES_URL)));
return;
}
/* Cancel previous download (if any)*/
if(m_reply){
m_reply->abort();
m_reply->deleteLater();
}
/* Start download */
m_startTime = QDateTime::currentDateTime().toTime_t();
QNetworkRequest netReq(url);
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
netReq.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
#endif
m_reply = m_manager->get(netReq);
/* Set file name */
m_fileName = m_updater->getDownloadUrl(UPDATES_URL).split("/").last();
if(m_fileName.isEmpty()){
m_fileName = QString("%1_Update_%2.bin")
.arg(qApp->applicationName())
.arg(m_updater->getLatestVersion(UPDATES_URL));
}
/* Prepare download directory */
if(!DOWNLOAD_DIR.exists())
DOWNLOAD_DIR.mkpath(".");
/* Remove previous downloads(if any)*/
QFile::remove(DOWNLOAD_DIR.filePath(m_fileName));
/* Show UI controls */
m_ui->progressControls->show();
showNormal();
/* Update UI when download progress changes or download finishes */
connect(m_reply, &QNetworkReply::downloadProgress, this, &UpdaterWindow::updateProgress);
connect(m_reply, &QNetworkReply::finished, this, &UpdaterWindow::onDownloadFinished);
}
+開啟安裝檔案
void
UpdaterWindow::openDownloadFolder(const
QString
&file)
{
/*
Notify
the
user
of
the
problem
*/
QString
extension
=
file.split(".").last();
QMessageBox::information(this,
tr("Open
Error"),
tr("It
seems
that
your
OS
does
not
have
an
"
"application
that
can
handle
*.%1
files.
"
"We'll
open
the
downloads
folder
for
you.")
.arg(extension),
QMessageBox::Ok);
/*
Get
the
full
path
list
of
the
downloaded
file
*/
QString
native_path
=
QDir::toNativeSeparators(QDir(file).absolutePath());
QStringList
directories
=
native_path.split(QDir::separator());
/*
Remove
file
name
from
list
to
get
the
folder
of
the
update
file
*/
directories.removeLast();
QString
path
=
directories.join (QDir::separator());
/*
Get
valid
URL
and
open
it
*/
QUrl
url
=
QUrl::fromLocalFile(QDir(path).absolutePath());
QDesktopServices::openUrl(url);
}
+下載進度更新
m_reply
=
m_manager->get(netReq);
/*
Set
file
name
*/
m_fileName
=
m_updater->getDownloadUrl(UPDATES_URL).split("/").last();
if(m_fileName.isEmpty()){
m_fileName
=
QString("%1_Update_%2.bin")
.arg(qApp->applicationName())
.arg(m_updater->getLatestVersion(UPDATES_URL));
}
/*
Prepare
download
directory
*/
if(!DOWNLOAD_DIR.exists())
DOWNLOAD_DIR.mkpath(".");
/*
Remove
previous
downloads(if
any)*/
QFile::remove(DOWNLOAD_DIR.filePath(m_fileName));
/*
Show
UI
controls
*/
m_ui->progressControls->show();
showNormal();
/*
Update
UI
when
download
progress
changes
or
download
finishes
*/
connect(m_reply,
&QNetworkReply::downloadProgress,
this,
&UpdaterWindow::updateProgress);
connect(m_reply,
&QNetworkReply::finished,
this,
&UpdaterWindow::onDownloadFinished);
資料庫儲存筆記檔案(注意特殊符號在SQL語句中的轉換)
*/
bool
DBManager::addNote(NoteData*
note)
{
QSqlQuery
query;
QString
emptyStr;
qint64
epochTimeDateCreated =
note->creationDateTime()
.toMSecsSinceEpoch();
QString
content
=
note->content()
.replace("'","''")
.replace(QChar('\x0'),
emptyStr);
QString
fullTitle
=
note->fullTitle()
.replace("'","''")
.replace(QChar('\x0'),
emptyStr);
qint64
epochTimeDateLastModified
=
note->lastModificationdateTime().isNull()
?
epochTimeDateCreated
:
note->lastModificationdateTime().toMSecsSinceEpoch();
QString
queryStr
=
QString("INSERT
INTO
active_notes
"
"(creation_date,
modification_date,
deletion_date,
content,
full_title)
"
"VALUES
(%1,
%2,
-1,
'%3',
'%4');")
.arg(epochTimeDateCreated)
.arg(epochTimeDateLastModified)
.arg(content)
.arg(fullTitle);
query.exec(queryStr);
return
(query.numRowsAffected()
==
1);
}
+資料庫放入執行緒處理 + 安全刪除執行緒
MainWindow::~MainWindow()
{
delete ui;
m_dbThread->quit();
m_dbThread->wait();
delete m_dbThread;
}
+獲取所有筆記檔案(使用Qlist儲存)
/*!
* \brief DBManager::getAllNotes
* \return
*/
QList<NoteData *> DBManager::getAllNotes()
{
QList<NoteData *> noteList;
QSqlQuery query;
query.prepare("SELECT * FROM active_notes");
bool status = query.exec();
if(status){
while(query.next()){
NoteData* note = new NoteData(this);
int id = query.value(0).toInt();
qint64 epochDateTimeCreation = query.value(1).toLongLong();
QDateTime dateTimeCreation = QDateTime::fromMSecsSinceEpoch(epochDateTimeCreation);
qint64 epochDateTimeModification= query.value(2).toLongLong();
QDateTime dateTimeModification = QDateTime::fromMSecsSinceEpoch(epochDateTimeModification);
QString content = query.value(4).toString();
QString fullTitle = query.value(5).toString();
note->setId(id);
note->setCreationDateTime(dateTimeCreation);
note->setLastModificationDateTime(dateTimeModification);
note->setContent(content);
note->setFullTitle(fullTitle);
noteList.push_back(note);
}
}
return noteList;
}
+筆記的增刪改查 資料庫操作
+更新一條筆記
bool DBManager::updateNote(NoteData* note)
{
QSqlQuery query;
QString emptyStr;
int id = note->id();
qint64 epochTimeDateModified = note->lastModificationdateTime().toMSecsSinceEpoch();
QString content = note->content().replace(QChar('\x0'), emptyStr);
QString fullTitle = note->fullTitle().replace(QChar('\x0'), emptyStr);
query.prepare(QStringLiteral("UPDATE active_notes SET modification_date = :date, content = :content, "
"full_title = :title WHERE id = :id"));
query.bindValue(QStringLiteral(":date"), epochTimeDateModified);
query.bindValue(QStringLiteral(":content"), content);
query.bindValue(QStringLiteral(":title"), fullTitle);
query.bindValue(QStringLiteral(":id"), id);
if (!query.exec()) {
qWarning () << __func__ << ": " << query.lastError();
}
return (query.numRowsAffected() == 1);
}