Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support paste image #593

Merged
merged 4 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 34 additions & 8 deletions src/iptux/DialogBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,10 +202,10 @@
/* 转到下一个文件节点 */
tlist = g_slist_next(tlist);
}
//计算待发送文件总计大小
// 计算待发送文件总计大小
totalsendsize = 0;
if (gtk_tree_model_get_iter_first(model, &iter)) {
do { //遍历待发送model
do { // 遍历待发送model

Check warning on line 208 in src/iptux/DialogBase.cpp

View check run for this annotation

Codecov / codecov/patch

src/iptux/DialogBase.cpp#L208

Added line #L208 was not covered by tests
gtk_tree_model_get(model, &iter, 4, &file, -1);
totalsendsize += file->filesize;
} while (gtk_tree_model_iter_next(model, &iter));
Expand Down Expand Up @@ -261,6 +261,8 @@
gtk_container_add(GTK_CONTAINER(sw), widget);
g_signal_connect_swapped(widget, "drag-data-received",
G_CALLBACK(DragDataReceived), this);
g_signal_connect_swapped(widget, "paste-clipboard",
G_CALLBACK(DialogBase::OnPasteClipboard), this);
g_datalist_set_data(&widset, "input-textview-widget", widget);

/* 功能按钮 */
Expand Down Expand Up @@ -487,7 +489,7 @@
return;
}

list = selection_data_get_path(data); //获取所有文件
list = selection_data_get_path(data); // 获取所有文件

Check warning on line 492 in src/iptux/DialogBase.cpp

View check run for this annotation

Codecov / codecov/patch

src/iptux/DialogBase.cpp#L492

Added line #L492 was not covered by tests
dlgpr->AttachEnclosure(list);
g_slist_foreach(list, GFunc(g_free), NULL);
g_slist_free(list);
Expand Down Expand Up @@ -601,7 +603,7 @@
auto dlg = self;

model = gtk_tree_view_get_model(GTK_TREE_VIEW(widget));
//从中心结点删除
// 从中心结点删除
TreeSel = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
list = gtk_tree_selection_get_selected_rows(TreeSel, NULL);
if (!list)
Expand All @@ -615,9 +617,9 @@
list = g_list_next(list);
}
g_list_free(list);
//从列表中删除
// 从列表中删除
RemoveSelectedFromTree(GTK_WIDGET(widget));
//重新计算待发送文件大小
// 重新计算待发送文件大小
dlg->UpdateFileSendUI(dlg);
}

Expand Down Expand Up @@ -659,7 +661,7 @@
g_datalist_set_data_full(&mdlset, "enclosure-model", model,
GDestroyNotify(g_object_unref));
g_datalist_set_data(&widset, "file-send-treeview-widget", treeview);
//保存this指针,在后面消息响应函数中用到
// 保存this指针,在后面消息响应函数中用到
g_object_set_data(G_OBJECT(treeview), "dialog", this);
gtk_container_add(GTK_CONTAINER(sw), treeview);
gtk_box_pack_end(GTK_BOX(vbox), sw, TRUE, TRUE, 0);
Expand Down Expand Up @@ -757,7 +759,7 @@
model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview));
sentsize = 0;
if (gtk_tree_model_get_iter_first(model, &iter)) {
do { //遍历待发送model
do { // 遍历待发送model

Check warning on line 762 in src/iptux/DialogBase.cpp

View check run for this annotation

Codecov / codecov/patch

src/iptux/DialogBase.cpp#L762

Added line #L762 was not covered by tests
gtk_tree_model_get(model, &iter, 4, &file, -1);
if (file->finishedsize == file->filesize) {
gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, "tip-finish", -1);
Expand Down Expand Up @@ -793,4 +795,28 @@
return grpinf->getInputBuffer();
}

void DialogBase::OnPasteClipboard(DialogBase* self, GtkTextView* textview) {
GtkClipboard* clipboard;
GtkTextBuffer* buffer;
GtkTextIter iter;

clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
buffer = gtk_text_view_get_buffer(textview);
gtk_text_buffer_get_iter_at_mark(buffer, &iter,
gtk_text_buffer_get_insert(buffer));
if (gtk_clipboard_wait_is_text_available(clipboard)) {
Comment on lines +798 to +807
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Consider adding logging for clipboard operations

Adding logging statements within the OnPasteClipboard method can help in tracking clipboard operations and diagnosing issues if the clipboard content is not pasted correctly.

gchar* text = gtk_clipboard_wait_for_text(clipboard);
if (text) {
gtk_text_buffer_insert(buffer, &iter, text, -1);
g_free(text);
}
} else if (gtk_clipboard_wait_is_image_available(clipboard)) {
GdkPixbuf* pixbuf = gtk_clipboard_wait_for_image(clipboard);
if (pixbuf) {
gtk_text_buffer_insert_pixbuf(buffer, &iter, pixbuf);
g_object_unref(pixbuf);
}
}
}

} // namespace iptux
13 changes: 7 additions & 6 deletions src/iptux/DialogBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class DialogBase : public SessionAbstract, public sigc::trackable {
static gint EnclosureTreePopup(DialogBase* self, GdkEvent* event);
static gboolean UpdateFileSendUI(DialogBase* dlggrp);
static void RemoveSelectedEnclosure(DialogBase* self);
static void OnPasteClipboard(DialogBase* self, GtkTextView* textview);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Consider adding documentation for OnPasteClipboard

Adding a brief comment or documentation for the OnPasteClipboard method in the header file can help other developers understand its purpose and usage.

Suggested change
static void OnPasteClipboard(DialogBase* self, GtkTextView* textview);
/**
* Handles the paste action from the clipboard to the specified text view.
*
* @param self Pointer to the DialogBase instance.
* @param textview Pointer to the GtkTextView where the clipboard content will be pasted.
*/
static void OnPasteClipboard(DialogBase* self, GtkTextView* textview);


protected:
Application* app;
Expand All @@ -91,12 +92,12 @@ class DialogBase : public SessionAbstract, public sigc::trackable {

GtkListStore* fileSendModel = 0;

GData* widset; //窗体集
GData* mdlset; //数据model集
GData* dtset; //通用数据集
GroupInfo* grpinf; //群组信息
int64_t totalsendsize; //总计待发送大小(包括已发送)
struct timeval lasktime; //上一次更新UI的时间
GData* widset; // 窗体集
GData* mdlset; // 数据model集
GData* dtset; // 通用数据集
GroupInfo* grpinf; // 群组信息
int64_t totalsendsize; // 总计待发送大小(包括已发送)
struct timeval lasktime; // 上一次更新UI的时间
guint timersend; // 发送文件界面更新计时器ID
};

Expand Down
14 changes: 10 additions & 4 deletions src/iptux/DialogPeer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "config.h"
#include "DialogPeer.h"

#include "UiModels.h"
#include <cinttypes>

#include <sys/socket.h>
Expand Down Expand Up @@ -52,6 +53,7 @@
sigc::mem_fun(*this, &DialogPeer::onNewFileReceived));
app->getCoreThread()->sigGroupInfoUpdated.connect(
sigc::mem_fun(*this, &DialogPeer::onGroupInfoUpdated));
init();
}

/**
Expand All @@ -73,9 +75,7 @@
if (grpinf->getDialog())
return;

DialogPeer* dlgpr;
dlgpr = new DialogPeer(app, grpinf);
dlgpr->init();
new DialogPeer(app, grpinf);

Check warning on line 78 in src/iptux/DialogPeer.cpp

View check run for this annotation

Codecov / codecov/patch

src/iptux/DialogPeer.cpp#L78

Added line #L78 was not covered by tests
}

void DialogPeer::init() {
Expand All @@ -97,6 +97,7 @@
makeActionEntry("request_shared_resources",
G_ACTION_CALLBACK(onRequestSharedResources)),
makeActionEntry("send_message", G_ACTION_CALLBACK(onSendMessage)),
makeActionEntry("paste", G_ACTION_CALLBACK(onPaste)),
};
g_action_map_add_action_entries(G_ACTION_MAP(window), win_entries,
G_N_ELEMENTS(win_entries), this);
Expand Down Expand Up @@ -265,7 +266,7 @@
gtk_box_pack_start(GTK_BOX(box), hpaned, TRUE, TRUE, 0);
g_signal_connect(hpaned, "notify::position", G_CALLBACK(PanedDivideChanged),
&dtset);
/*/* 加入聊天历史记录&输入区域 */
/* 加入聊天历史记录&输入区域 */
vpaned = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
g_object_set_data(G_OBJECT(vpaned), "position-name",
(gpointer) "historyinput-paned-divide");
Expand Down Expand Up @@ -492,6 +493,11 @@
g_cthrd->SendAskShared(self.grpinf->getMembers()[0]);
}

void DialogPeer::onPaste(void*, void*, DialogPeer* self) {
GtkTextView* textview = GTK_TEXT_VIEW(self->inputTextviewWidget);
DialogBase::OnPasteClipboard(self, textview);
}

void DialogPeer::insertPicture() {
GtkWidget* widget;
GtkTextBuffer* buffer;
Expand Down
9 changes: 5 additions & 4 deletions src/iptux/DialogPeer.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class DialogPeer : public DialogBase {
void refreshSendAction();
std::string GetTitle();

//回调处理部分
// 回调处理部分
private:
static void onRecvTreeSelectionChanged(DialogPeer& self, GtkTreeSelection*);
static void onAcceptButtonClicked(DialogPeer* self);
Expand All @@ -91,6 +91,7 @@ class DialogPeer : public DialogBase {
DialogBase::AttachFolder(&self);
}
static void onRequestSharedResources(void*, void*, DialogPeer& self);
static void onPaste(void*, void*, DialogPeer* self);
static void onSendMessage(void*, void*, DialogPeer& self) {
DialogBase::SendMessage(&self);
}
Expand All @@ -105,9 +106,9 @@ class DialogPeer : public DialogBase {
protected:
GtkApplicationWindow* window;
std::shared_ptr<IptuxConfig> config;
int64_t torcvsize; //总计待接收大小(包括已接收)
int64_t rcvdsize; //总计已接收大小
guint timerrcv; //接收文件界面更新计时器ID
int64_t torcvsize; // 总计待接收大小(包括已接收)
int64_t rcvdsize; // 总计已接收大小
guint timerrcv; // 接收文件界面更新计时器ID
GtkWidget* fileToReceiveTreeviewWidget = nullptr;
gulong sigId = 0;
};
Expand Down
24 changes: 23 additions & 1 deletion src/iptux/DialogPeerTest.cpp
Original file line number Diff line number Diff line change
@@ -1,20 +1,42 @@
#include "Application.h"
#include "gtest/gtest.h"

#include "iptux-utils/TestHelper.h"
#include "iptux/DialogPeer.h"
#include "iptux/TestHelper.h"
#include "iptux/UiCoreThread.h"

using namespace std;
using namespace iptux;

static void do_action(DialogPeer* w, const char* name) {
GActionMap* m = G_ACTION_MAP(w->getWindow());
g_action_activate(g_action_map_lookup_action(m, name), NULL);
}

TEST(DialogPeer, Constructor) {
Application* app = CreateApplication();

PPalInfo pal = make_shared<PalInfo>("127.0.0.1", 2425);
app->getCoreThread()->AttachPalToList(pal);

GroupInfo* grpinf = app->getCoreThread()->GetPalRegularItem(pal.get());
DialogPeer::PeerDialogEntry(app, grpinf);
DialogPeer* dlgpr = new DialogPeer(app, grpinf);

auto clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
gtk_clipboard_set_text(clipboard, "hello world", -1);
do_action(dlgpr, "paste");

GError* error = NULL;
auto pixbuf =
gdk_pixbuf_new_from_file(testDataPath("iptux.png").c_str(), &error);
if (error != nullptr) {
ASSERT_TRUE(false) << error->message;
g_error_free(error);
}
gtk_clipboard_set_image(clipboard, pixbuf);
do_action(dlgpr, "paste");
g_object_unref(pixbuf);

DestroyApplication(app);
}
Loading