safePasswords #36
@ -1,6 +1,6 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## Squawk 0.1.4 (UNRELEASED)
|
## Squawk 0.1.4 (Apr 14, 2020)
|
||||||
### New features
|
### New features
|
||||||
- message line now is in the same window with roster (new window dialog is still able to opened on context menu)
|
- message line now is in the same window with roster (new window dialog is still able to opened on context menu)
|
||||||
- several new ways to manage your account password:
|
- several new ways to manage your account password:
|
||||||
@ -8,6 +8,7 @@
|
|||||||
- store it in config jammed (local hashing with the constant seed, not secure at all but might look like it is)
|
- store it in config jammed (local hashing with the constant seed, not secure at all but might look like it is)
|
||||||
- ask the account password on each program launch
|
- ask the account password on each program launch
|
||||||
- store it in KWallet which is dynamically loaded
|
- store it in KWallet which is dynamically loaded
|
||||||
|
- dragging into conversation now attach files
|
||||||
|
|
||||||
### Bug fixes
|
### Bug fixes
|
||||||
- never updating MUC avatars now get updated
|
- never updating MUC avatars now get updated
|
||||||
@ -15,6 +16,7 @@
|
|||||||
- statuses now behave better: they wrap if they don't fit, you can select them, you can follow links from there
|
- statuses now behave better: they wrap if they don't fit, you can select them, you can follow links from there
|
||||||
- messages and statuses don't loose content if you use < ore > symbols
|
- messages and statuses don't loose content if you use < ore > symbols
|
||||||
- now avatars of those who are not in the MUC right now but was also display next to the message
|
- now avatars of those who are not in the MUC right now but was also display next to the message
|
||||||
|
- fix crash on attempt to attach the same file for the second time
|
||||||
|
|
||||||
|
|
||||||
## Squawk 0.1.3 (Mar 31, 2020)
|
## Squawk 0.1.3 (Mar 31, 2020)
|
||||||
|
@ -109,9 +109,9 @@ add_dependencies(${CMAKE_PROJECT_NAME} translations)
|
|||||||
# Install the executable
|
# Install the executable
|
||||||
install(TARGETS squawk DESTINATION ${CMAKE_INSTALL_BINDIR})
|
install(TARGETS squawk DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||||
install(FILES ${QM_FILES} DESTINATION ${CMAKE_INSTALL_DATADIR}/squawk/l10n)
|
install(FILES ${QM_FILES} DESTINATION ${CMAKE_INSTALL_DATADIR}/squawk/l10n)
|
||||||
install(FILES squawk.svg DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps)
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/squawk.svg DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps)
|
||||||
install(FILES squawk48.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/48x48/apps RENAME squawk.png)
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/squawk48.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/48x48/apps RENAME squawk.png)
|
||||||
install(FILES squawk64.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/64x64/apps RENAME squawk.png)
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/squawk64.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/64x64/apps RENAME squawk.png)
|
||||||
install(FILES squawk128.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/128x128/apps RENAME squawk.png)
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/squawk128.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/128x128/apps RENAME squawk.png)
|
||||||
install(FILES squawk256.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/256x256/apps RENAME squawk.png)
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/squawk256.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/256x256/apps RENAME squawk.png)
|
||||||
install(FILES squawk.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/squawk.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
[![AUR version](https://img.shields.io/aur/version/squawk?style=flat-square)](https://aur.archlinux.org/packages/squawk/)
|
[![AUR version](https://img.shields.io/aur/version/squawk?style=flat-square)](https://aur.archlinux.org/packages/squawk/)
|
||||||
[![Liberapay patrons](https://img.shields.io/liberapay/patrons/macaw.me?logo=liberapay&style=flat-square)](https://liberapay.com/macaw.me)
|
[![Liberapay patrons](https://img.shields.io/liberapay/patrons/macaw.me?logo=liberapay&style=flat-square)](https://liberapay.com/macaw.me)
|
||||||
|
|
||||||
![Squawk screenshot](https://macaw.me/images/squawk/0.1.3.png)
|
![Squawk screenshot](https://macaw.me/images/squawk/0.1.4.png)
|
||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
|
|
||||||
@ -13,6 +13,7 @@
|
|||||||
- lmdb
|
- lmdb
|
||||||
- CMake 3.0 or higher
|
- CMake 3.0 or higher
|
||||||
- qxmpp 1.1.0 or higher
|
- qxmpp 1.1.0 or higher
|
||||||
|
- kwallet (optional)
|
||||||
|
|
||||||
### Getting
|
### Getting
|
||||||
|
|
||||||
|
@ -41,11 +41,6 @@ Core::PSE::KWallet::KWallet():
|
|||||||
if (sState == initial) {
|
if (sState == initial) {
|
||||||
lib.load();
|
lib.load();
|
||||||
|
|
||||||
if (!lib.isLoaded()) { //fallback from the build directory
|
|
||||||
lib.setFileName("./core/passwordStorageEngines/libkwalletWrapper.so");
|
|
||||||
lib.load();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lib.isLoaded()) {
|
if (lib.isLoaded()) {
|
||||||
openWallet = (OpenWallet) lib.resolve("openWallet");
|
openWallet = (OpenWallet) lib.resolve("openWallet");
|
||||||
networkWallet = (NetworkWallet) lib.resolve("networkWallet");
|
networkWallet = (NetworkWallet) lib.resolve("networkWallet");
|
||||||
@ -81,7 +76,9 @@ void Core::PSE::KWallet::open()
|
|||||||
{
|
{
|
||||||
if (sState == success) {
|
if (sState == success) {
|
||||||
if (cState == disconnected) {
|
if (cState == disconnected) {
|
||||||
wallet = openWallet(networkWallet(), 0, ::KWallet::Wallet::Asynchronous);
|
QString name;
|
||||||
|
networkWallet(name);
|
||||||
|
wallet = openWallet(name, 0, ::KWallet::Wallet::Asynchronous);
|
||||||
if (wallet) {
|
if (wallet) {
|
||||||
cState = connecting;
|
cState = connecting;
|
||||||
connect(wallet, SIGNAL(walletOpened(bool)), this, SLOT(onWalletOpened(bool)));
|
connect(wallet, SIGNAL(walletOpened(bool)), this, SLOT(onWalletOpened(bool)));
|
||||||
@ -89,6 +86,7 @@ void Core::PSE::KWallet::open()
|
|||||||
} else {
|
} else {
|
||||||
everError = true;
|
everError = true;
|
||||||
emit opened(false);
|
emit opened(false);
|
||||||
|
rejectPending();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
typedef ::KWallet::Wallet* (*OpenWallet)(const QString &, WId, ::KWallet::Wallet::OpenType);
|
typedef ::KWallet::Wallet* (*OpenWallet)(const QString &, WId, ::KWallet::Wallet::OpenType);
|
||||||
typedef const char* (*NetworkWallet)();
|
typedef void (*NetworkWallet)(QString&);
|
||||||
typedef void (*DeleteWallet)(::KWallet::Wallet*);
|
typedef void (*DeleteWallet)(::KWallet::Wallet*);
|
||||||
typedef int (*ReadPassword)(::KWallet::Wallet*, const QString&, QString&);
|
typedef int (*ReadPassword)(::KWallet::Wallet*, const QString&, QString&);
|
||||||
typedef int (*WritePassword)(::KWallet::Wallet*, const QString&, const QString&);
|
typedef int (*WritePassword)(::KWallet::Wallet*, const QString&, const QString&);
|
||||||
|
@ -8,8 +8,8 @@ extern "C" void deleteWallet(KWallet::Wallet* w) {
|
|||||||
w->deleteLater();
|
w->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" const char* networkWallet() {
|
extern "C" void networkWallet(QString& str) {
|
||||||
return KWallet::Wallet::NetworkWallet().toStdString().c_str();
|
str = KWallet::Wallet::NetworkWallet();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int readPassword(KWallet::Wallet* w, const QString &key, QString &value) {
|
extern "C" int readPassword(KWallet::Wallet* w, const QString &key, QString &value) {
|
||||||
|
2
main.cpp
2
main.cpp
@ -42,7 +42,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
QApplication::setApplicationName("squawk");
|
QApplication::setApplicationName("squawk");
|
||||||
QApplication::setApplicationDisplayName("Squawk");
|
QApplication::setApplicationDisplayName("Squawk");
|
||||||
QApplication::setApplicationVersion("0.1.3");
|
QApplication::setApplicationVersion("0.1.4");
|
||||||
|
|
||||||
QTranslator qtTranslator;
|
QTranslator qtTranslator;
|
||||||
qtTranslator.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
|
qtTranslator.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
|
||||||
|
2
order.h
2
order.h
@ -29,7 +29,7 @@ namespace W
|
|||||||
template <typename data_type, typename comparator = std::less<data_type>>
|
template <typename data_type, typename comparator = std::less<data_type>>
|
||||||
class Order
|
class Order
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
class Duplicates:
|
class Duplicates:
|
||||||
public Utils::Exception
|
public Utils::Exception
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# Maintainer: Yury Gubich <blue@macaw.me>
|
# Maintainer: Yury Gubich <blue@macaw.me>
|
||||||
pkgname=squawk
|
pkgname=squawk
|
||||||
pkgver=0.1.3
|
pkgver=0.1.4
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="An XMPP desktop messenger, written on pure c++ (qt)"
|
pkgdesc="An XMPP desktop messenger, written on pure c++ (qt)"
|
||||||
arch=('i686' 'x86_64')
|
arch=('i686' 'x86_64')
|
||||||
@ -8,8 +8,10 @@ url="https://git.macaw.me/blue/squawk"
|
|||||||
license=('GPL3')
|
license=('GPL3')
|
||||||
depends=('hicolor-icon-theme' 'desktop-file-utils' 'lmdb' 'qxmpp>=1.1.0')
|
depends=('hicolor-icon-theme' 'desktop-file-utils' 'lmdb' 'qxmpp>=1.1.0')
|
||||||
makedepends=('cmake>=3.3' 'imagemagick' 'qt5-tools')
|
makedepends=('cmake>=3.3' 'imagemagick' 'qt5-tools')
|
||||||
|
optdepends=('kwallet: secure password storage (requires rebuild)')
|
||||||
|
|
||||||
source=("$pkgname-$pkgver.tar.gz")
|
source=("$pkgname-$pkgver.tar.gz")
|
||||||
sha256sums=('adb172bb7d5b81bd9b83b192481a79ac985877e81604f401b3f2a08613b359bc')
|
sha256sums=('3b290381eaf15a35d24a58a36c29eee375a4ea77b606124982a063d7ecf98870')
|
||||||
build() {
|
build() {
|
||||||
cd "$srcdir/squawk"
|
cd "$srcdir/squawk"
|
||||||
cmake . -D CMAKE_INSTALL_PREFIX=/usr -D CMAKE_BUILD_TYPE=Release
|
cmake . -D CMAKE_INSTALL_PREFIX=/usr -D CMAKE_BUILD_TYPE=Release
|
||||||
|
@ -33,9 +33,9 @@ static const QRegularExpression urlReg("(?<!<a\\shref=['\"])(?<!<img\\ssrc=['\"]
|
|||||||
"(?:https?|ftp):\\/\\/"
|
"(?:https?|ftp):\\/\\/"
|
||||||
"\\w+"
|
"\\w+"
|
||||||
"(?:"
|
"(?:"
|
||||||
"[\\w\\.\\/\\:\\;\\?\\&\\=\\@\\%\\#\\+\\-]?"
|
"[\\w\\.\\,\\/\\:\\;\\?\\&\\=\\@\\%\\#\\+\\-]?"
|
||||||
"(?:"
|
"(?:"
|
||||||
"\\([\\w\\.\\/\\:\\;\\?\\&\\=\\@\\%\\#\\+\\-]+\\)"
|
"\\([\\w\\.\\,\\/\\:\\;\\?\\&\\=\\@\\%\\#\\+\\-]+\\)"
|
||||||
")?"
|
")?"
|
||||||
")*"
|
")*"
|
||||||
")");
|
")");
|
||||||
|
@ -119,6 +119,10 @@ p, li { white-space: pre-wrap; }
|
|||||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html></source>
|
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html></source>
|
||||||
<translation></translation>
|
<translation></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Drop files here to attach them to your message</source>
|
||||||
|
<translation>Бросьте файлы сюда для того что бы прикрепить их к сообщению</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>Global</name>
|
<name>Global</name>
|
||||||
@ -637,6 +641,10 @@ to be displayed as %1</source>
|
|||||||
<source>Password for account %1</source>
|
<source>Password for account %1</source>
|
||||||
<translation>Пароль для учетной записи %1</translation>
|
<translation>Пароль для учетной записи %1</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Please select a contact to start chatting</source>
|
||||||
|
<translation>Выберите контакт или группу что бы начать переписку</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>VCard</name>
|
<name>VCard</name>
|
||||||
|
@ -34,7 +34,8 @@ Squawk::Squawk(QWidget *parent) :
|
|||||||
requestedAccountsForPasswords(),
|
requestedAccountsForPasswords(),
|
||||||
prompt(0),
|
prompt(0),
|
||||||
currentConversation(0),
|
currentConversation(0),
|
||||||
restoreSelection()
|
restoreSelection(),
|
||||||
|
needToRestore(false)
|
||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
m_ui->roster->setModel(&rosterModel);
|
m_ui->roster->setModel(&rosterModel);
|
||||||
@ -1139,6 +1140,7 @@ void Squawk::onRosterSelectionChanged(const QModelIndex& current, const QModelIn
|
|||||||
if (id != 0) {
|
if (id != 0) {
|
||||||
delete id;
|
delete id;
|
||||||
}
|
}
|
||||||
|
needToRestore = true;
|
||||||
restoreSelection = previous;
|
restoreSelection = previous;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1204,5 +1206,8 @@ void Squawk::onRosterSelectionChanged(const QModelIndex& current, const QModelIn
|
|||||||
|
|
||||||
void Squawk::onContextAboutToHide()
|
void Squawk::onContextAboutToHide()
|
||||||
{
|
{
|
||||||
|
if (needToRestore) {
|
||||||
|
needToRestore = false;
|
||||||
m_ui->roster->selectionModel()->setCurrentIndex(restoreSelection, QItemSelectionModel::ClearAndSelect);
|
m_ui->roster->selectionModel()->setCurrentIndex(restoreSelection, QItemSelectionModel::ClearAndSelect);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -126,6 +126,7 @@ private:
|
|||||||
QInputDialog* prompt;
|
QInputDialog* prompt;
|
||||||
Conversation* currentConversation;
|
Conversation* currentConversation;
|
||||||
QModelIndex restoreSelection;
|
QModelIndex restoreSelection;
|
||||||
|
bool needToRestore;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void closeEvent(QCloseEvent * event) override;
|
void closeEvent(QCloseEvent * event) override;
|
||||||
|
12
ui/squawk.ui
12
ui/squawk.ui
@ -129,8 +129,18 @@
|
|||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>26</pointsize>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string><html><head/><body><p><span style=" font-size:26pt;">Please select a contact to start chatting</span></p></body></html></string>
|
<string>Please select a contact to start chatting</string>
|
||||||
|
</property>
|
||||||
|
<property name="textFormat">
|
||||||
|
<enum>Qt::PlainText</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
<set>Qt::AlignCenter</set>
|
<set>Qt::AlignCenter</set>
|
||||||
|
@ -44,6 +44,7 @@ Conversation::Conversation(bool muc, Models::Account* acc, const QString pJid, c
|
|||||||
statusIcon(0),
|
statusIcon(0),
|
||||||
statusLabel(0),
|
statusLabel(0),
|
||||||
filesLayout(0),
|
filesLayout(0),
|
||||||
|
overlay(new QWidget()),
|
||||||
filesToAttach(),
|
filesToAttach(),
|
||||||
scroll(down),
|
scroll(down),
|
||||||
manualSliderChange(false),
|
manualSliderChange(false),
|
||||||
@ -92,15 +93,26 @@ Conversation::Conversation(bool muc, Models::Account* acc, const QString pJid, c
|
|||||||
line->setMyAvatarPath(acc->getAvatarPath());
|
line->setMyAvatarPath(acc->getAvatarPath());
|
||||||
line->setMyName(acc->getName());
|
line->setMyName(acc->getName());
|
||||||
|
|
||||||
QFont nf = m_ui->nameLabel->font();
|
QGridLayout* gr = static_cast<QGridLayout*>(layout());
|
||||||
nf.setBold(true);
|
QLabel* progressLabel = new QLabel(tr("Drop files here to attach them to your message"));
|
||||||
nf.setPointSize(nf.pointSize() + 2);
|
gr->addWidget(overlay, 0, 0, 2, 1);
|
||||||
m_ui->nameLabel->setFont(nf);
|
QVBoxLayout* nl = new QVBoxLayout();
|
||||||
|
QGraphicsOpacityEffect* opacity = new QGraphicsOpacityEffect();
|
||||||
QFont sf = statusLabel->font();
|
opacity->setOpacity(0.8);
|
||||||
sf.setItalic(true);
|
overlay->setLayout(nl);
|
||||||
sf.setPointSize(sf.pointSize() - 2);
|
overlay->setBackgroundRole(QPalette::Base);
|
||||||
statusLabel->setFont(sf);
|
overlay->setAutoFillBackground(true);
|
||||||
|
overlay->setGraphicsEffect(opacity);
|
||||||
|
progressLabel->setAlignment(Qt::AlignCenter);
|
||||||
|
QFont pf = progressLabel->font();
|
||||||
|
pf.setBold(true);
|
||||||
|
pf.setPointSize(26);
|
||||||
|
progressLabel->setWordWrap(true);
|
||||||
|
progressLabel->setFont(pf);
|
||||||
|
nl->addStretch();
|
||||||
|
nl->addWidget(progressLabel);
|
||||||
|
nl->addStretch();
|
||||||
|
overlay->hide();
|
||||||
|
|
||||||
applyVisualEffects();
|
applyVisualEffects();
|
||||||
}
|
}
|
||||||
@ -362,11 +374,17 @@ void Conversation::addAttachedFile(const QString& path)
|
|||||||
Badge* badge = new Badge(path, info.fileName(), QIcon::fromTheme(type.iconName()));
|
Badge* badge = new Badge(path, info.fileName(), QIcon::fromTheme(type.iconName()));
|
||||||
|
|
||||||
connect(badge, &Badge::close, this, &Conversation::onBadgeClose);
|
connect(badge, &Badge::close, this, &Conversation::onBadgeClose);
|
||||||
filesToAttach.push_back(badge); //TODO neet to check if there are any duplicated ids
|
try {
|
||||||
|
filesToAttach.push_back(badge);
|
||||||
filesLayout->addWidget(badge);
|
filesLayout->addWidget(badge);
|
||||||
if (filesLayout->count() == 1) {
|
if (filesLayout->count() == 1) {
|
||||||
filesLayout->setContentsMargins(3, 3, 3, 3);
|
filesLayout->setContentsMargins(3, 3, 3, 3);
|
||||||
}
|
}
|
||||||
|
} catch (const W::Order<Badge*, Badge::Comparator>::Duplicates& e) {
|
||||||
|
delete badge;
|
||||||
|
} catch (...) {
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Conversation::removeAttachedFile(Badge* badge)
|
void Conversation::removeAttachedFile(Badge* badge)
|
||||||
@ -421,6 +439,53 @@ void Conversation::setFeedFrames(bool top, bool right, bool bottom, bool left)
|
|||||||
static_cast<DropShadowEffect*>(m_ui->scrollArea->graphicsEffect())->setFrame(top, right, bottom, left);
|
static_cast<DropShadowEffect*>(m_ui->scrollArea->graphicsEffect())->setFrame(top, right, bottom, left);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Conversation::dragEnterEvent(QDragEnterEvent* event)
|
||||||
|
{
|
||||||
|
bool accept = false;
|
||||||
|
if (event->mimeData()->hasUrls()) {
|
||||||
|
QList<QUrl> list = event->mimeData()->urls();
|
||||||
|
for (const QUrl& url : list) {
|
||||||
|
if (url.isLocalFile()) {
|
||||||
|
QFileInfo info(url.toLocalFile());
|
||||||
|
if (info.isReadable() && info.isFile()) {
|
||||||
|
accept = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (accept) {
|
||||||
|
event->acceptProposedAction();
|
||||||
|
overlay->show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Conversation::dragLeaveEvent(QDragLeaveEvent* event)
|
||||||
|
{
|
||||||
|
overlay->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Conversation::dropEvent(QDropEvent* event)
|
||||||
|
{
|
||||||
|
bool accept = false;
|
||||||
|
if (event->mimeData()->hasUrls()) {
|
||||||
|
QList<QUrl> list = event->mimeData()->urls();
|
||||||
|
for (const QUrl& url : list) {
|
||||||
|
if (url.isLocalFile()) {
|
||||||
|
QFileInfo info(url.toLocalFile());
|
||||||
|
if (info.isReadable() && info.isFile()) {
|
||||||
|
addAttachedFile(info.canonicalFilePath());
|
||||||
|
accept = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (accept) {
|
||||||
|
event->acceptProposedAction();
|
||||||
|
}
|
||||||
|
overlay->hide();
|
||||||
|
}
|
||||||
|
|
||||||
bool VisibilityCatcher::eventFilter(QObject* obj, QEvent* event)
|
bool VisibilityCatcher::eventFilter(QObject* obj, QEvent* event)
|
||||||
{
|
{
|
||||||
if (event->type() == QEvent::Show) {
|
if (event->type() == QEvent::Show) {
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QScopedPointer>
|
#include <QScopedPointer>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
|
#include <QMimeData>
|
||||||
|
#include <QFileInfo>
|
||||||
|
|
||||||
#include "shared/message.h"
|
#include "shared/message.h"
|
||||||
#include "order.h"
|
#include "order.h"
|
||||||
@ -105,6 +107,9 @@ protected:
|
|||||||
void addAttachedFile(const QString& path);
|
void addAttachedFile(const QString& path);
|
||||||
void removeAttachedFile(Badge* badge);
|
void removeAttachedFile(Badge* badge);
|
||||||
void clearAttachedFiles();
|
void clearAttachedFiles();
|
||||||
|
void dragEnterEvent(QDragEnterEvent* event) override;
|
||||||
|
void dragLeaveEvent(QDragLeaveEvent* event) override;
|
||||||
|
void dropEvent(QDropEvent* event) override;
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void onEnterPressed();
|
void onEnterPressed();
|
||||||
@ -138,6 +143,7 @@ protected:
|
|||||||
QLabel* statusIcon;
|
QLabel* statusIcon;
|
||||||
QLabel* statusLabel;
|
QLabel* statusLabel;
|
||||||
FlowLayout* filesLayout;
|
FlowLayout* filesLayout;
|
||||||
|
QWidget* overlay;
|
||||||
W::Order<Badge*, Badge::Comparator> filesToAttach;
|
W::Order<Badge*, Badge::Comparator> filesToAttach;
|
||||||
Scroll scroll;
|
Scroll scroll;
|
||||||
bool manualSliderChange;
|
bool manualSliderChange;
|
||||||
|
@ -16,10 +16,10 @@
|
|||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="horizontalLayout">
|
<property name="acceptDrops">
|
||||||
<property name="spacing">
|
<bool>true</bool>
|
||||||
<number>0</number>
|
|
||||||
</property>
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
@ -32,7 +32,7 @@
|
|||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item row="0" column="0">
|
||||||
<widget class="QWidget" name="widget" native="true">
|
<widget class="QWidget" name="widget" native="true">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||||
@ -115,6 +115,13 @@
|
|||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="nameLabel">
|
<widget class="QLabel" name="nameLabel">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>12</pointsize>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
@ -128,6 +135,12 @@
|
|||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>8</pointsize>
|
||||||
|
<italic>true</italic>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
@ -230,7 +243,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>520</width>
|
<width>520</width>
|
||||||
<height>392</height>
|
<height>385</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
@ -258,7 +271,7 @@
|
|||||||
<zorder>widget_3</zorder>
|
<zorder>widget_3</zorder>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="1" column="0">
|
||||||
<widget class="QWidget" name="widget_2" native="true">
|
<widget class="QWidget" name="widget_2" native="true">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||||
|
@ -126,7 +126,11 @@ VCard::VCard(const QString& jid, bool edit, QWidget* parent):
|
|||||||
overlay->setAutoFillBackground(true);
|
overlay->setAutoFillBackground(true);
|
||||||
overlay->setGraphicsEffect(opacity);
|
overlay->setGraphicsEffect(opacity);
|
||||||
progressLabel->setAlignment(Qt::AlignCenter);
|
progressLabel->setAlignment(Qt::AlignCenter);
|
||||||
progressLabel->setStyleSheet("font: 16pt");
|
QFont pf = progressLabel->font();
|
||||||
|
pf.setBold(true);
|
||||||
|
pf.setPointSize(26);
|
||||||
|
progressLabel->setFont(pf);
|
||||||
|
progressLabel->setWordWrap(true);
|
||||||
nl->addStretch();
|
nl->addStretch();
|
||||||
nl->addWidget(progress);
|
nl->addWidget(progress);
|
||||||
nl->addWidget(progressLabel);
|
nl->addWidget(progressLabel);
|
||||||
|
Loading…
Reference in New Issue
Block a user