Files
ukui-paste/mainwindow.cpp

808 lines
28 KiB
C++
Raw Permalink Normal View History

2020-12-09 10:09:29 +08:00
/*
* Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/&gt;.
*
*/
#include <QApplication>
#include <QScreen>
#include <QLabel>
#include <QSizePolicy>
#include <QScroller>
#include <QFile>
#include <QMessageBox>
#include <QMimeData>
#include <QCryptographicHash>
#include <QImage>
#include <QFileInfo>
#include <QFileIconProvider>
#include <QUrl>
#include <QBuffer>
#include <QMenu>
#include <QAction>
#include <QMutex>
#include <QMutexLocker>
#include <QShortcut>
#include <QEvent>
#include <QDebug>
2020-12-21 16:09:51 +08:00
#include <QTextEdit>
#include "mainwindow.h"
#include <KF5/KWindowSystem/KWindowEffects>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
MainWindow::MainWindow(QWidget *parent)
2020-12-09 10:09:29 +08:00
: QMainWindow(parent),
__main_frame(new MainFrame(this)),
__hide_animation(new QPropertyAnimation(this, "pos")),
__shortcut(new DoubleCtrlShortcut(this)),
__hide_state(true),
__clipboard(QApplication::clipboard()),
__current_item(nullptr)
{
2020-12-09 10:09:29 +08:00
/* 初始化与任务栏交互的dbus和gsetting */
2020-12-21 16:09:51 +08:00
initPanelDbusGsetting();
2021-07-23 16:42:17 +08:00
/* 分辨率是否变化 */
2020-12-09 10:09:29 +08:00
desktoparea_change();
2020-12-09 10:09:29 +08:00
QObject::connect(this->__clipboard, &QClipboard::dataChanged, [this](void) {
QTimer::singleShot(100, this, SLOT(clipboard_later()));
});
QObject::connect(this->__hide_animation, &QPropertyAnimation::finished, [this](void) {
if (this->__hide_animation->direction() == QAbstractAnimation::Forward) {
/* Hidden stage */
this->hide();
}
});
2020-12-09 10:09:29 +08:00
QObject::connect(this->__shortcut, &DoubleCtrlShortcut::activated, [this](void) {
2021-07-23 16:42:17 +08:00
/* 整体窗口位置 */
2020-12-21 16:09:51 +08:00
window_xy();
2020-12-09 10:09:29 +08:00
if (!this->isVisible())
this->show_window();
else
this->hide_window();
});
2020-12-21 16:09:51 +08:00
this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint |
Qt::BypassWindowManagerHint | Qt::SplashScreen);
this->setFocusPolicy(Qt::NoFocus);
this->setCentralWidget(this->__main_frame);
this->setAttribute(Qt::WA_TranslucentBackground, false);
this->enabledGlassEffect();
this->__main_frame->setGeometry(this->geometry());
this->__main_frame->setFocusPolicy(Qt::ClickFocus);
QObject::connect(this->__main_frame, SIGNAL(moveFocusPrevNext(bool)), this, SLOT(move_to_prev_next_focus_widget(bool)));
2020-12-09 10:09:29 +08:00
QShortcut *shortcut_search = new QShortcut(this);
shortcut_search->setKey(QKeySequence("Ctrl+f"));
QObject::connect(shortcut_search, &QShortcut::activated, [this](void) {
LineEdit *lineedit = this->__searchbar->findChild<LineEdit *>("", Qt::FindDirectChildrenOnly);
lineedit->setFocus();
});
2020-12-09 10:09:29 +08:00
this->initUI();
return;
}
2021-07-23 16:42:17 +08:00
void MainWindow::initPanelDbusGsetting() {
2020-12-21 16:09:51 +08:00
/* 链接任务栏Dbus接口获取任务栏高度和位置 */
m_pServiceInterface = new QDBusInterface(PANEL_DBUS_SERVICE, PANEL_DBUS_PATH, PANEL_DBUS_INTERFACE, QDBusConnection::sessionBus());
m_pServiceInterface->setTimeout(2147483647);
2020-12-09 10:09:29 +08:00
2020-12-21 16:09:51 +08:00
/* 链接任务栏dgsetting接口 */
if(QGSettings::isSchemaInstalled(UKUI_PANEL_SETTING))
m_pPanelSetting = new QGSettings(UKUI_PANEL_SETTING);
2020-12-09 10:09:29 +08:00
}
2020-12-21 16:09:51 +08:00
2021-07-23 16:42:17 +08:00
/* 获取桌面是否有改变 */
void MainWindow::desktoparea_change() {
2020-12-09 10:09:29 +08:00
QDesktopWidget* desktopWidget = QApplication::desktop();
2020-12-21 16:09:51 +08:00
connect(desktopWidget, &QDesktopWidget::resized, this, &MainWindow::window_xy);
2020-12-09 10:09:29 +08:00
}
2020-12-21 16:09:51 +08:00
2021-07-23 16:42:17 +08:00
/* 整体窗口位置 */
void MainWindow::window_xy() {
2020-12-09 10:09:29 +08:00
desktop_width();
desktop_height();
2021-07-23 16:42:17 +08:00
switch(getPanelSite()) {
2020-12-21 16:09:51 +08:00
case 0:
this->setGeometry(8, screenHeight*0.68, screenWidth-16, screenHeight*0.32-connectTaskBarDbus()-8);
break;
case 1:
this->setGeometry(8, screenHeight*0.68+connectTaskBarDbus(), screenWidth-16, screenHeight*0.32-connectTaskBarDbus()-8);
break;
case 2:
this->setGeometry(8+connectTaskBarDbus(), screenHeight*0.68, screenWidth-16-connectTaskBarDbus(), screenHeight*0.32-8);
break;
case 3:
this->setGeometry(8, screenHeight*0.68, screenWidth-16-connectTaskBarDbus(), screenHeight*0.32-8);
break;
default:
break;
}
2020-12-09 10:09:29 +08:00
}
2020-12-21 16:09:51 +08:00
2021-07-23 16:42:17 +08:00
/* 获取主桌面分辨率大小 */
int MainWindow::desktop_width() {
2020-12-09 10:09:29 +08:00
QRect screenRect1 = desktop->screenGeometry();
screenWidth = screenRect1.width();
return screenWidth;
}
int MainWindow::desktop_height(){
QRect screenRect2 = desktop->screenGeometry();
screenHeight = screenRect2.height();
return screenHeight;
}
2021-07-23 16:42:17 +08:00
/* 获取任务栏的大小 */
int MainWindow::connectTaskBarDbus() {
2020-12-21 16:09:51 +08:00
int panelHeight = 46;
if (m_pPanelSetting != nullptr) {
QStringList keys = m_pPanelSetting->keys();
if (keys.contains("panelsize")) {
panelHeight = m_pPanelSetting->get("panelsize").toInt();
}
} else {
QDBusMessage msg = m_pServiceInterface->call("GetPanelSize", QVariant("Hight"));
panelHeight = msg.arguments().at(0).toInt();
return panelHeight;
}
return panelHeight;
}
2021-07-23 16:42:17 +08:00
/* 获取任务栏位置 */
int MainWindow::getPanelSite() {
2020-12-21 16:09:51 +08:00
int panelPosition = 0;
if (m_pPanelSetting != nullptr) {
QStringList keys = m_pPanelSetting->keys();
if (keys.contains("panelposition")) {
panelPosition = m_pPanelSetting->get("panelposition").toInt();
}
} else {
QDBusMessage msg = m_pServiceInterface->call("GetPanelPosition", QVariant("Site"));
panelPosition = msg.arguments().at(0).toInt();
}
return panelPosition;
}
2020-12-09 10:09:29 +08:00
2021-07-23 16:42:17 +08:00
MainWindow::~MainWindow() {
2020-12-09 10:09:29 +08:00
delete this->__hide_animation;
}
2020-12-21 16:09:51 +08:00
2021-07-23 16:42:17 +08:00
bool MainWindow::event(QEvent *e){
2020-12-09 10:09:29 +08:00
if (e->type() == QEvent::ActivationChange) {
if (QApplication::activeWindow() != this)
this->hide_window();
}
2020-12-09 10:09:29 +08:00
return QMainWindow::event(e);
}
2021-07-23 16:42:17 +08:00
void MainWindow::showEvent(QShowEvent *event) {
2020-12-09 10:09:29 +08:00
QListWidgetItem *item = this->__scroll_widget->currentItem();
if(item) {
auto *widget = this->__scroll_widget->itemWidget(item);
/* Let the selected item has focus */
widget->setFocus();
this->__scroll_widget->scrollToItem(item);
}
2020-12-09 10:09:29 +08:00
/* That is a workaround for QListWidget pixel scroll */
int count = this->__scroll_widget->count();
if (count > 0) {
this->__scroll_widget->item(count-1)->setHidden(false);
}
2020-12-09 10:09:29 +08:00
QWidget::showEvent(event);
}
2021-07-23 16:42:17 +08:00
void MainWindow::hideEvent(QHideEvent *event) {
2020-12-09 10:09:29 +08:00
/* That is a workaround for QListWidget pixel scroll */
int count = this->__scroll_widget->count();
if(count > 0) {
this->__scroll_widget->item(count-1)->setHidden(true);
}
2020-12-09 10:09:29 +08:00
QWidget::hideEvent(event);
}
2021-07-23 16:42:17 +08:00
void MainWindow::show_window(void) {
2020-12-09 10:09:29 +08:00
this->__hide_animation->setDirection(QAbstractAnimation::Backward);
this->__hide_animation->start();
this->__hide_state = false;
this->activateWindow();
this->show();
}
2021-07-23 16:42:17 +08:00
void MainWindow::hide_window(void) {
2020-12-09 10:09:29 +08:00
if (this->__hide_state)
return;
2020-12-09 10:09:29 +08:00
this->__hide_animation->setDirection(QAbstractAnimation::Forward);
this->__hide_animation->start();
this->__hide_state = true;
}
2021-07-23 16:42:17 +08:00
void MainWindow::move_to_prev_next_focus_widget(bool prev) {
2020-12-09 10:09:29 +08:00
QListWidgetItem *item = this->__scroll_widget->selectedItems()[0];
PasteItem *widget = reinterpret_cast<PasteItem *>(this->__scroll_widget->itemWidget(item));
2020-12-09 10:09:29 +08:00
do {
if (prev) {
/* Get prev focus widget and isn't hidden */
widget = reinterpret_cast<PasteItem *>(widget->previousInFocusChain());
} else {
/* Get next focus widget and isn't hidden */
widget = reinterpret_cast<PasteItem *>(widget->nextInFocusChain());
}
} while (widget->isHidden());
widget->setFocus();
}
2021-07-23 16:42:17 +08:00
void MainWindow::initUI(void) {
/* 搜索部分 */
2020-12-09 10:09:29 +08:00
this->__searchbar = new SearchBar(this->__main_frame, this->width()/3, 40);
QObject::connect(this->__searchbar, &SearchBar::textChanged, [this](const QString &text) {
int temp_current_item_row = -1;
int show_row_count = 0;
2020-12-09 10:09:29 +08:00
/* Store current row num when first time searching */
if (this->__current_item == nullptr) {
this->__current_item = this->__scroll_widget->currentItem();
}
2020-12-09 10:09:29 +08:00
for (int i = 0; i < this->__scroll_widget->count(); i++) {
QListWidgetItem *item = this->__scroll_widget->item(i);
PasteItem *widget = reinterpret_cast<PasteItem *>(this->__scroll_widget->itemWidget(item));
if (!widget->text().toLower().contains(text.toLower())) {
item->setHidden(true);
} else {
item->setHidden(false);
show_row_count++;
2020-12-09 10:09:29 +08:00
if (temp_current_item_row == -1) {
temp_current_item_row = i;
}
}
}
2020-12-09 10:09:29 +08:00
/* That is the first showing item */
if (temp_current_item_row != -1) {
this->__scroll_widget->item(temp_current_item_row)->setSelected(true);
this->__scroll_widget->scrollToItem(this->__scroll_widget->item(temp_current_item_row));
}
2021-07-23 16:42:17 +08:00
/* 这一段会导致空数据搜索时程序崩溃 */
// if (show_row_count == this->__scroll_widget->count()) {
// /* restore current row in search before */
// this->__current_item->setSelected(true);
// this->__scroll_widget->scrollToItem(this->__current_item);
// this->__current_item = nullptr;
// }
2020-12-09 10:09:29 +08:00
});
QObject::connect(this->__searchbar, &SearchBar::selectItem, [this](void) {
QListWidgetItem *item = this->__scroll_widget->selectedItems()[0];
PasteItem *widget = reinterpret_cast<PasteItem *>(this->__scroll_widget->itemWidget(item));
this->__current_item = nullptr;
widget->copyData();
});
QObject::connect(this->__searchbar, SIGNAL(moveFocusPrevNext(bool)), this, SLOT(move_to_prev_next_focus_widget(bool)));
2021-07-23 16:42:17 +08:00
/* 分类按钮部分 */
2020-12-21 16:09:51 +08:00
this->__classify1 = new PushButton(this->__main_frame);
2021-07-23 16:42:17 +08:00
this->__classify1->setText("all");
2020-12-21 16:09:51 +08:00
this->__classify1->setFixedSize(80, 30);
this->__classify1->setFlat(true);
this->__classify2 = new PushButton(this->__main_frame);
2021-07-23 16:42:17 +08:00
this->__classify2->setText("fuwenben");
2020-12-21 16:09:51 +08:00
this->__classify2->setFixedSize(80, 30);
this->__classify2->setFlat(true);
this->__classify3 = new PushButton(this->__main_frame);
2021-07-23 16:42:17 +08:00
this->__classify3->setText("pics");
2020-12-21 16:09:51 +08:00
this->__classify3->setFixedSize(80, 30);
this->__classify3->setFlat(true);
this->__classify4 = new PushButton(this->__main_frame);
2021-07-23 16:42:17 +08:00
this->__classify4->setText("wenjian");
2020-12-21 16:09:51 +08:00
this->__classify4->setFixedSize(80, 30);
this->__classify4->setFlat(true);
this->__classify5 = new PushButton(this->__main_frame);
2021-07-23 16:42:17 +08:00
this->__classify5->setText("wenben");
2020-12-21 16:09:51 +08:00
this->__classify5->setFixedSize(80, 30);
this->__classify5->setFlat(true);
2021-07-23 16:42:17 +08:00
this->__classify6 = new PushButton(this->__main_frame);
this->__classify6->setText("clean");
this->__classify6->setFixedSize(80, 30);
this->__classify6->setFlat(true);
2021-07-23 16:42:17 +08:00
QObject::connect(this->__classify1, &PushButton::clicked, [this](void) {
this->reloadData(0);
2020-12-21 16:09:51 +08:00
});
QObject::connect(this->__classify2, &PushButton::clicked, [this](void) {
2021-07-23 16:42:17 +08:00
this->reloadData(1);
2020-12-21 16:09:51 +08:00
});
QObject::connect(this->__classify3, &PushButton::clicked, [this](void) {
2021-07-23 16:42:17 +08:00
this->reloadData(2);
2020-12-21 16:09:51 +08:00
});
QObject::connect(this->__classify4, &PushButton::clicked, [this](void) {
2021-07-23 16:42:17 +08:00
this->reloadData(3);
2020-12-21 16:09:51 +08:00
});
QObject::connect(this->__classify5, &PushButton::clicked, [this](void) {
2021-07-23 16:42:17 +08:00
this->reloadData(4);
});
QObject::connect(this->__classify6, &PushButton::clicked, [this](void) {
this->__db.deleleAllPasteItem();
2020-12-21 16:09:51 +08:00
this->reloadData(0);
});
2021-07-23 16:42:17 +08:00
/* 列表展示部分 */
2020-12-09 10:09:29 +08:00
this->__scroll_widget = new QListWidget(this->__main_frame);
this->__scroll_widget->setSelectionMode(QAbstractItemView::SingleSelection);
this->__scroll_widget->setHorizontalScrollMode(QListWidget::ScrollPerPixel);
this->__scroll_widget->setFlow(QListView::LeftToRight);
this->__scroll_widget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
this->__scroll_widget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
this->__scroll_widget->setViewMode(QListView::ListMode);
this->__scroll_widget->setEditTriggers(QAbstractItemView::NoEditTriggers);
this->__scroll_widget->setFrameShape(QListWidget::NoFrame);
this->__scroll_widget->setSpacing(10);
this->__scroll_widget->setWrapping(false);
this->__scroll_widget->setFocusPolicy(Qt::NoFocus);
QScroller::grabGesture(this->__scroll_widget, QScroller::LeftMouseButtonGesture);
QObject::connect(this->__scroll_widget, &QListWidget::currentItemChanged, [this](void) {
this->__scroll_widget->update();
});
2020-12-21 16:09:51 +08:00
2021-07-23 16:42:17 +08:00
/* 整体布局 */
2020-12-09 10:09:29 +08:00
QHBoxLayout *hlayout = new QHBoxLayout();
hlayout->addWidget(this->__searchbar);
2020-12-21 16:09:51 +08:00
hlayout->addWidget(this->__classify1);
hlayout->addWidget(this->__classify2);
hlayout->addWidget(this->__classify3);
hlayout->addWidget(this->__classify4);
2021-07-23 16:42:17 +08:00
hlayout->addWidget(this->__classify5);
2020-12-09 10:09:29 +08:00
hlayout->addStretch();
2021-07-23 16:42:17 +08:00
hlayout->addWidget(this->__classify6);
2020-12-09 10:09:29 +08:00
QVBoxLayout *vlayout = new QVBoxLayout();
2021-07-23 16:42:17 +08:00
2020-12-09 10:09:29 +08:00
vlayout->addLayout(hlayout);
vlayout->addWidget(this->__scroll_widget);
2020-12-09 10:09:29 +08:00
this->__main_frame->setLayout(vlayout);
/* need this for resize this->__scroll_widget size */
this->__main_frame->show();
2020-12-09 10:09:29 +08:00
/* load data from database */
2020-12-21 16:09:51 +08:00
this->reloadData(0);
}
2021-07-23 16:42:17 +08:00
/* 处理复制粘贴的展示数据 */
void MainWindow::reloadData(int format) {
/* 第一次打开时创造数据表 */
2020-12-09 10:09:29 +08:00
if (!this->__db.isTableExist()) {
this->__db.createTable();
return;
}
2021-07-23 16:42:17 +08:00
/* 打开时判断是否数据为空 */
if(!this->__db.isDataExist()){
qDebug("null");
}
/* 增加展示区域 */
2020-12-21 16:09:51 +08:00
int y =this->__scroll_widget->count();
for (int x=0 ;x<=y;x++){
delete this->__scroll_widget->takeItem(0);
int y = y+1;
}
2020-12-09 10:09:29 +08:00
for (auto itemData : this->__db.loadData()) {
2020-12-21 16:09:51 +08:00
/* 时间过长删除 */
2020-12-09 10:09:29 +08:00
if (QDateTime::currentDateTime().toSecsSinceEpoch() - itemData->time.toSecsSinceEpoch() > (60 * 60 * 24 * 7)) {
this->__db.delelePasteItem(itemData->md5);
continue;
}
2021-07-23 16:42:17 +08:00
/* 不同分类展示内容判断 */
if(format == 1) {
2020-12-21 16:09:51 +08:00
PasteItem *widgetRichText = this->insertItemWidgetRichText();
if (itemData->mimeData->hasHtml() && !itemData->mimeData->text().isEmpty()) {
widgetRichText->setRichText(itemData->mimeData->html(), itemData->mimeData->text());
} else {
/* No data, remove it */
2020-12-09 10:09:29 +08:00
delete this->__scroll_widget->takeItem(0);
continue;
}
2020-12-21 16:09:51 +08:00
widgetRichText->setTime(itemData->time);
widgetRichText->setIcon(itemData->icon);
2021-07-23 16:42:17 +08:00
} else if (format == 2) {
2020-12-21 16:09:51 +08:00
PasteItem *widgetImage = this->insertItemWidgetImage();
if (itemData->mimeData->hasImage()) {
widgetImage->setImage(itemData->image);
} else {
/* No data, remove it */
delete this->__scroll_widget->takeItem(0);
continue;
}
widgetImage->setTime(itemData->time);
widgetImage->setIcon(itemData->icon);
2021-07-23 16:42:17 +08:00
} else if(format == 3) {
2020-12-21 16:09:51 +08:00
PasteItem *widgetUrls = this->insertItemWidgetUrls();
QList<QUrl> urls = itemData->mimeData->urls();
if (itemData->mimeData->hasUrls()) {
if (!widgetUrls->setUrls(urls)) {
this->__db.delelePasteItem(itemData->md5);
delete this->__scroll_widget->takeItem(0);
continue;
}
} else {
/* No data, remove it */
delete this->__scroll_widget->takeItem(0);
continue;
}
widgetUrls->setTime(itemData->time);
widgetUrls->setIcon(itemData->icon);
2021-07-23 16:42:17 +08:00
} else if (format == 4) {
2020-12-21 16:09:51 +08:00
PasteItem *widgetPlainText = this->insertItemWidgetPlainText();
if (itemData->mimeData->hasText() && !itemData->mimeData->text().isEmpty()) {
widgetPlainText->setPlainText(itemData->mimeData->text().trimmed());
} else {
/* No data, remove it */
delete this->__scroll_widget->takeItem(0);
continue;
}
widgetPlainText->setTime(itemData->time);
widgetPlainText->setIcon(itemData->icon);
2020-12-09 10:09:29 +08:00
} else {
2020-12-21 16:09:51 +08:00
PasteItem *widget = this->insertItemWidget();
2021-07-23 16:42:17 +08:00
/* 复制网页内容 空内容时 链接 图片 文本 以及文件地址 */
2020-12-21 16:09:51 +08:00
if (itemData->mimeData->hasHtml() && !itemData->mimeData->text().isEmpty()) {
widget->setRichText(itemData->mimeData->html(), itemData->mimeData->text());
} else if (itemData->mimeData->hasImage()) {
widget->setImage(itemData->image);
} else if (itemData->mimeData->hasUrls()) {
QList<QUrl> urls = itemData->mimeData->urls();
if (!widget->setUrls(urls)) {
this->__db.delelePasteItem(itemData->md5);
delete this->__scroll_widget->takeItem(0);
continue;
}
} else if (itemData->mimeData->hasText() && !itemData->mimeData->text().isEmpty()) {
widget->setPlainText(itemData->mimeData->text().trimmed());
} else {
/* No data, remove it */
delete this->__scroll_widget->takeItem(0);
continue;
}
widget->setTime(itemData->time);
widget->setIcon(itemData->icon);
2020-12-09 10:09:29 +08:00
}
2020-12-09 10:09:29 +08:00
this->__scroll_widget->item(0)->setData(Qt::UserRole, QVariant::fromValue(*itemData));
}
}
/* Insert a PasteItem into listwidget */
2021-07-23 16:42:17 +08:00
/* 在列表中插入一个可以粘贴的内容块 */
PasteItem *MainWindow::insertItemWidget(void) {
2020-12-09 10:09:29 +08:00
QListWidgetItem *item = new QListWidgetItem;
auto *widget = new PasteItem(nullptr, item);
2020-12-09 10:09:29 +08:00
QObject::connect(widget, &PasteItem::hideWindow, [this](void) {
this->hide_window();
});
2020-12-09 10:09:29 +08:00
QRect rect = QApplication::primaryScreen()->geometry();
/* resize item, It's use for pasteitem frame */
item->setSizeHint(QSize(rect.width()/6, 1));
2020-12-09 10:09:29 +08:00
this->__scroll_widget->insertItem(0, item);
this->__scroll_widget->setCurrentRow(0);
this->__scroll_widget->setItemWidget(item, widget);
this->resetItemTabOrder();
2020-12-09 10:09:29 +08:00
return widget;
}
2021-07-23 16:42:17 +08:00
PasteItem *MainWindow::insertItemWidgetRichText(void) {
2020-12-21 16:09:51 +08:00
QListWidgetItem *item = new QListWidgetItem;
auto *widgetRichText = new PasteItem(nullptr, item);
QObject::connect(widgetRichText, &PasteItem::hideWindow, [this](void) {
this->hide_window();
});
QRect rect = QApplication::primaryScreen()->geometry();
/* resize item, It's use for pasteitem frame */
item->setSizeHint(QSize(rect.width()/6, 1));
this->__scroll_widget->insertItem(0, item);
this->__scroll_widget->setCurrentRow(0);
this->__scroll_widget->setItemWidget(item, widgetRichText);
this->resetItemTabOrder();
return widgetRichText;
}
2021-07-23 16:42:17 +08:00
PasteItem *MainWindow::insertItemWidgetImage(void) {
2020-12-21 16:09:51 +08:00
QListWidgetItem *item = new QListWidgetItem;
auto *widgetImage = new PasteItem(nullptr, item);
QObject::connect(widgetImage, &PasteItem::hideWindow, [this](void) {
this->hide_window();
});
QRect rect = QApplication::primaryScreen()->geometry();
/* resize item, It's use for pasteitem frame */
item->setSizeHint(QSize(rect.width()/6, 1));
this->__scroll_widget->insertItem(0, item);
this->__scroll_widget->setCurrentRow(0);
this->__scroll_widget->setItemWidget(item, widgetImage);
this->resetItemTabOrder();
return widgetImage;
}
2021-07-23 16:42:17 +08:00
PasteItem *MainWindow::insertItemWidgetUrls(void) {
2020-12-21 16:09:51 +08:00
QListWidgetItem *item = new QListWidgetItem;
auto *widgetUrls = new PasteItem(nullptr, item);
QObject::connect(widgetUrls, &PasteItem::hideWindow, [this](void) {
this->hide_window();
});
QRect rect = QApplication::primaryScreen()->geometry();
/* resize item, It's use for pasteitem frame */
item->setSizeHint(QSize(rect.width()/6, 1));
this->__scroll_widget->insertItem(0, item);
this->__scroll_widget->setCurrentRow(0);
this->__scroll_widget->setItemWidget(item, widgetUrls);
this->resetItemTabOrder();
return widgetUrls;
}
2021-07-23 16:42:17 +08:00
PasteItem *MainWindow::insertItemWidgetPlainText(void) {
2020-12-21 16:09:51 +08:00
QListWidgetItem *item = new QListWidgetItem;
auto *widgetPlainText = new PasteItem(nullptr, item);
QObject::connect(widgetPlainText, &PasteItem::hideWindow, [this](void) {
this->hide_window();
});
QRect rect = QApplication::primaryScreen()->geometry();
/* resize item, It's use for pasteitem frame */
item->setSizeHint(QSize(rect.width()/6, 1));
this->__scroll_widget->insertItem(0, item);
this->__scroll_widget->setCurrentRow(0);
this->__scroll_widget->setItemWidget(item, widgetPlainText);
this->resetItemTabOrder();
return widgetPlainText;
}
2021-07-23 16:42:17 +08:00
void MainWindow::resetItemTabOrder(void) {
2020-12-09 10:09:29 +08:00
int count = this->__scroll_widget->count();
2020-12-09 10:09:29 +08:00
for (int i = 0; i < count-1; i++) {
QWidget *first = this->__scroll_widget->itemWidget(this->__scroll_widget->item(i));
QWidget *second = this->__scroll_widget->itemWidget(this->__scroll_widget->item(i+1));
QWidget::setTabOrder(first, second);
}
}
QMutex clipboard_mutex;
2021-07-23 16:42:17 +08:00
void MainWindow::clipboard_later(void) {
2020-12-09 10:09:29 +08:00
QMutexLocker locker(&clipboard_mutex);
const QMimeData *mime_data = this->__clipboard->mimeData();
PasteItem *widget = nullptr;
QByteArray md5_data;
ItemData itemData;
itemData.mimeData = new QMimeData;
2020-12-09 10:09:29 +08:00
foreach (QString format, mime_data->formats()) {
itemData.mimeData->setData(format, mime_data->data(format));
}
if (mime_data->hasImage()) {
itemData.image = qvariant_cast<QImage>(mime_data->imageData());
}
2020-12-09 10:09:29 +08:00
widget = this->insertItemWidget();
2020-12-09 10:09:29 +08:00
if (itemData.mimeData->hasHtml() && !itemData.mimeData->text().isEmpty()) {
widget->setRichText(itemData.mimeData->html(), itemData.mimeData->text());
md5_data = itemData.mimeData->text().toLocal8Bit();
2020-12-09 10:09:29 +08:00
} else if (itemData.mimeData->hasImage()) {
widget->setImage(itemData.image);
2020-12-09 10:09:29 +08:00
QBuffer buffer(&md5_data);
buffer.open(QIODevice::WriteOnly);
itemData.image.save(&buffer, "png");
buffer.close();
} else if (itemData.mimeData->hasUrls()) {
QList<QUrl> urls = itemData.mimeData->urls();
foreach(QUrl url, urls) {
md5_data += url.toEncoded();
}
widget->setUrls(urls);
} else if (itemData.mimeData->hasText() && !itemData.mimeData->text().isEmpty()) {
widget->setPlainText(itemData.mimeData->text().trimmed());
md5_data = itemData.mimeData->text().toLocal8Bit();
} else {
/* No data, remove it */
QListWidgetItem *tmp_item = this->__scroll_widget->item(0);
this->__scroll_widget->removeItemWidget(tmp_item);
delete tmp_item;
return;
}
2020-12-09 10:09:29 +08:00
itemData.md5 = QCryptographicHash::hash(md5_data, QCryptographicHash::Md5);
/* Remove dup item */
for (int i = 1; i < this->__scroll_widget->count(); i++) {
QListWidgetItem *tmp_item = this->__scroll_widget->item(i);
ItemData tmp_itemData = tmp_item->data(Qt::UserRole).value<ItemData>();
/* They have same md5, remove it */
if (itemData.md5 == tmp_itemData.md5) {
/* move icon from old data */
itemData.icon = tmp_itemData.icon;
this->__db.delelePasteItem(tmp_itemData.md5);
this->__scroll_widget->removeItemWidget(tmp_item);
delete tmp_item;
continue;
}
/* remove the data if it's too old (than a week) */
if (QDateTime::currentDateTime().toSecsSinceEpoch() - tmp_itemData.time.toSecsSinceEpoch() >= (60 * 60 * 24 * 7)) {
this->__db.delelePasteItem(tmp_itemData.md5);
this->__scroll_widget->removeItemWidget(tmp_item);
delete tmp_item;
}
}
2020-12-09 10:09:29 +08:00
itemData.time = QDateTime::currentDateTime();
widget->setTime(itemData.time);
2020-12-09 10:09:29 +08:00
if (itemData.icon.isNull()) {
/* Find and set icon who triggers the clipboard */
itemData.icon = this->getClipboardOwnerIcon();
}
widget->setIcon(itemData.icon);
this->__scroll_widget->item(0)->setData(Qt::UserRole, QVariant::fromValue(itemData));
this->__db.insertPasteItem(&itemData);
}
2021-07-23 16:42:17 +08:00
QPixmap MainWindow::getClipboardOwnerIcon(void) {
2020-12-09 10:09:29 +08:00
QPixmap pixmap;
#ifdef Q_OS_LINUX
2020-12-09 10:09:29 +08:00
int i = 0;
Display *display = XOpenDisplay(NULL);
Atom clipboard_atom = XInternAtom(display, "CLIPBOARD", False);
/* Search from [-100, 100] */
Window clipboard_owner_win = XGetSelectionOwner(display, clipboard_atom) - 100;
2020-12-09 10:09:29 +08:00
unsigned long nitems, bytesafter;
unsigned char *ret;
int format;
Atom type;
Atom wm_icon_atom = XInternAtom(display, "_NET_WM_ICON", True);
again:
2020-12-09 10:09:29 +08:00
/* Get the width of the icon */
XGetWindowProperty(display,
clipboard_owner_win,
wm_icon_atom,
0, 1, 0,
XA_CARDINAL,
&type,
&format,
&nitems,
&bytesafter,
&ret);
if (!ret) {
/* FIXME: In fact, Get clipboard window id from XLIB is not the
* actual window id, but it is strange that his actual ID is
* near this, between -100 and +100.
*
* I didn't find out what happened, but he seems to be working.
* if anyone finds a good way, please let me know.
*/
clipboard_owner_win++;
if (i++ > 200) {
XCloseDisplay(display);
qDebug() << "Not found icon, Use default Linux logo";
pixmap.convertFromImage(QImage(":/resources/ubuntu.png"));
return pixmap;
}
2020-12-09 10:09:29 +08:00
goto again;
}
2020-12-09 10:09:29 +08:00
int width = *(int *)ret;
XFree(ret);
2020-12-09 10:09:29 +08:00
/* Get the height of the Icon */
XGetWindowProperty(display,
clipboard_owner_win,
wm_icon_atom,
1, 1, 0,
XA_CARDINAL,
&type,
&format,
&nitems,
&bytesafter,
&ret);
if (!ret) {
qDebug() << "No X11 Icon height Found.";
XCloseDisplay(display);
2020-12-09 10:09:29 +08:00
return pixmap;
}
2020-12-09 10:09:29 +08:00
int height = *(int *)ret;
XFree(ret);
2020-12-09 10:09:29 +08:00
/* Get data from Icon */
int size = width * height;
XGetWindowProperty(display,
clipboard_owner_win,
wm_icon_atom,
2, size, 0,
XA_CARDINAL,
&type,
&format,
&nitems,
&bytesafter,
&ret);
if (!ret) {
qDebug() << "No X11 Icon Data Found.";
XCloseDisplay(display);
2020-12-09 10:09:29 +08:00
return pixmap;
}
2020-12-09 10:09:29 +08:00
unsigned long *imgArr = (unsigned long*)(ret);
std::vector<uint32_t> imgARGB32(size);
for(int i=0; i<size; ++i)
imgARGB32[i] = (uint32_t)(imgArr[i]);
2020-12-09 10:09:29 +08:00
QImage *image = new QImage((uchar*)imgARGB32.data(), width, height, QImage::Format_ARGB32);
pixmap.convertFromImage(*image);
2020-12-09 10:09:29 +08:00
XFree(ret);
delete image;
XCloseDisplay(display);
#endif
2020-12-09 10:09:29 +08:00
return pixmap;
}
2020-12-21 16:09:51 +08:00
2021-07-23 16:42:17 +08:00
void MainWindow::enabledGlassEffect(void) {
#ifdef Q_OS_LINUX
2020-12-09 10:09:29 +08:00
KWindowEffects::enableBlurBehind(this->winId(), true);
#endif
}