mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-21 06:45:39 -06:00
CtrlCore: Gtk: Added support for pasting/droping Files (RM #401)
git-svn-id: svn://ultimatepp.org/upp/trunk@5698 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
11e17eacdd
commit
2594709c17
7 changed files with 84 additions and 34 deletions
|
|
@ -131,7 +131,8 @@ public:
|
||||||
~ImageGdk();
|
~ImageGdk();
|
||||||
};
|
};
|
||||||
|
|
||||||
Image ImageFromPixbufUnref(GdkPixbuf *pixbuf);
|
String FilesClipFromUrisFree(gchar **uris);
|
||||||
|
String ImageClipFromPixbufUnref(GdkPixbuf *pixbuf);
|
||||||
|
|
||||||
GdkAtom GAtom(const String& id);
|
GdkAtom GAtom(const String& id);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,7 @@ String Ctrl::GtkDataGet(GtkSelectionData *s)
|
||||||
|
|
||||||
String Ctrl::Gclipboard::Get(const String& fmt)
|
String Ctrl::Gclipboard::Get(const String& fmt)
|
||||||
{
|
{
|
||||||
|
LLOG("Ctrl::Gclipboard::Get " << fmt);
|
||||||
if(fmt == "text") {
|
if(fmt == "text") {
|
||||||
gchar *s = gtk_clipboard_wait_for_text(clipboard);
|
gchar *s = gtk_clipboard_wait_for_text(clipboard);
|
||||||
if(s) {
|
if(s) {
|
||||||
|
|
@ -99,16 +100,19 @@ String Ctrl::Gclipboard::Get(const String& fmt)
|
||||||
return Null;
|
return Null;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if(fmt == "image") {
|
if(fmt == "image")
|
||||||
Image img = ImageFromPixbufUnref(gtk_clipboard_wait_for_image(clipboard));
|
return ImageClipFromPixbufUnref(gtk_clipboard_wait_for_image(clipboard));
|
||||||
return StoreAsString(img); // Not very optimal...
|
else
|
||||||
}
|
if(fmt == "files")
|
||||||
|
return FilesClipFromUrisFree(gtk_clipboard_wait_for_uris(clipboard));
|
||||||
else
|
else
|
||||||
return GtkDataGet(gtk_clipboard_wait_for_contents(clipboard, GAtom(fmt)));
|
return GtkDataGet(gtk_clipboard_wait_for_contents(clipboard, GAtom(fmt)));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Ctrl::Gclipboard::IsAvailable(const String& fmt)
|
bool Ctrl::Gclipboard::IsAvailable(const String& fmt)
|
||||||
{
|
{
|
||||||
|
if(fmt == "files")
|
||||||
|
return gtk_clipboard_wait_is_uris_available(clipboard);
|
||||||
if(fmt == "text")
|
if(fmt == "text")
|
||||||
return gtk_clipboard_wait_is_text_available(clipboard);
|
return gtk_clipboard_wait_is_text_available(clipboard);
|
||||||
if(fmt == "image")
|
if(fmt == "image")
|
||||||
|
|
@ -336,12 +340,20 @@ bool IsAvailableFiles(PasteClip& clip)
|
||||||
return clip.IsAvailable("files");
|
return clip.IsAvailable("files");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO:
|
Vector<String> GetClipFiles(const String& data)
|
||||||
|
{
|
||||||
|
Vector<String> r;
|
||||||
|
Vector<String> f = Split(data, '\n');
|
||||||
|
for(int i = 0; i < f.GetCount(); i++)
|
||||||
|
if(f[i].StartsWith("file://"))
|
||||||
|
r.Add(f[i].Mid(7));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
Vector<String> GetFiles(PasteClip& clip)
|
Vector<String> GetFiles(PasteClip& clip)
|
||||||
{
|
{
|
||||||
GuiLock __;
|
GuiLock __;
|
||||||
Vector<String> f;
|
return GetClipFiles(clip.Get("files"));
|
||||||
return f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ptr<Ctrl> Ctrl::sel_ctrl;
|
Ptr<Ctrl> Ctrl::sel_ctrl;
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,7 @@
|
||||||
static Index<String> dnd_targets;
|
static Index<String> dnd_targets;
|
||||||
static String dnd_text_target;
|
static String dnd_text_target;
|
||||||
static String dnd_image_target;
|
static String dnd_image_target;
|
||||||
|
static String dnd_files_target;
|
||||||
static String dnd_data;
|
static String dnd_data;
|
||||||
static String dnd_data_fmt;
|
static String dnd_data_fmt;
|
||||||
static bool dnd_data_wait;
|
static bool dnd_data_wait;
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,7 @@ int Ctrl::DoDragAndDrop(const char *fmts, const Image& sample, dword actions,
|
||||||
Index<String> Ctrl::dnd_targets;
|
Index<String> Ctrl::dnd_targets;
|
||||||
String Ctrl::dnd_text_target;
|
String Ctrl::dnd_text_target;
|
||||||
String Ctrl::dnd_image_target;
|
String Ctrl::dnd_image_target;
|
||||||
|
String Ctrl::dnd_files_target;
|
||||||
GtkWidget *Ctrl::dnd_widget;
|
GtkWidget *Ctrl::dnd_widget;
|
||||||
GdkDragContext *Ctrl::dnd_context;
|
GdkDragContext *Ctrl::dnd_context;
|
||||||
guint Ctrl::dnd_time;
|
guint Ctrl::dnd_time;
|
||||||
|
|
@ -161,13 +162,17 @@ void Ctrl::DndTargets(GdkDragContext *context)
|
||||||
{
|
{
|
||||||
static Index<String> text_targets;
|
static Index<String> text_targets;
|
||||||
static Index<String> image_targets;
|
static Index<String> image_targets;
|
||||||
|
static Index<String> files_targets;
|
||||||
ONCELOCK {
|
ONCELOCK {
|
||||||
GtkTargetList *target_list = gtk_target_list_new (NULL, 0);
|
GtkTargetList *target_list = gtk_target_list_new (NULL, 0);
|
||||||
gtk_target_list_add_text_targets (target_list, 0);
|
gtk_target_list_add_text_targets(target_list, 0);
|
||||||
ToIndex(target_list, text_targets);
|
ToIndex(target_list, text_targets);
|
||||||
GtkTargetList *target_list2 = gtk_target_list_new (NULL, 0);
|
GtkTargetList *target_list2 = gtk_target_list_new (NULL, 0);
|
||||||
gtk_target_list_add_image_targets (target_list2, 0, TRUE);
|
gtk_target_list_add_image_targets(target_list2, 0, TRUE);
|
||||||
ToIndex(target_list2, image_targets);
|
ToIndex(target_list2, image_targets);
|
||||||
|
GtkTargetList *target_list3 = gtk_target_list_new (NULL, 0);
|
||||||
|
gtk_target_list_add_uri_targets(target_list3, 0);
|
||||||
|
ToIndex(target_list3, files_targets);
|
||||||
}
|
}
|
||||||
dnd_targets.Clear();
|
dnd_targets.Clear();
|
||||||
dnd_text_target.Clear();
|
dnd_text_target.Clear();
|
||||||
|
|
@ -184,6 +189,12 @@ void Ctrl::DndTargets(GdkDragContext *context)
|
||||||
if(dnd_image_target.IsEmpty())
|
if(dnd_image_target.IsEmpty())
|
||||||
dnd_image_target = g;
|
dnd_image_target = g;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
if(files_targets.Find(g) >= 0) {
|
||||||
|
dnd_targets.Add("files");
|
||||||
|
if(dnd_files_target.IsEmpty())
|
||||||
|
dnd_files_target = g;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
dnd_targets.Add(g);
|
dnd_targets.Add(g);
|
||||||
}
|
}
|
||||||
|
|
@ -193,7 +204,7 @@ void Ctrl::GtkDragDataReceived(GtkWidget *widget, GdkDragContext *context,
|
||||||
gint x, gint y, GtkSelectionData *data,
|
gint x, gint y, GtkSelectionData *data,
|
||||||
guint info, guint time, gpointer user_data)
|
guint info, guint time, gpointer user_data)
|
||||||
{
|
{
|
||||||
LLOG("GtkDragDataReceived");
|
LLOG("GtkDragDataReceived " << dnd_data_fmt);
|
||||||
dnd_data_wait = false;
|
dnd_data_wait = false;
|
||||||
if(dnd_data_fmt == "text") {
|
if(dnd_data_fmt == "text") {
|
||||||
guchar *s = gtk_selection_data_get_text(data);
|
guchar *s = gtk_selection_data_get_text(data);
|
||||||
|
|
@ -203,10 +214,11 @@ void Ctrl::GtkDragDataReceived(GtkWidget *widget, GdkDragContext *context,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if(dnd_data_fmt == "image") {
|
if(dnd_data_fmt == "image")
|
||||||
Image img = ImageFromPixbufUnref(gtk_selection_data_get_pixbuf(data));
|
dnd_data = ImageClipFromPixbufUnref(gtk_selection_data_get_pixbuf(data));
|
||||||
dnd_data = StoreAsString(img); // Not very optimal...
|
else
|
||||||
}
|
if(dnd_data_fmt == "files")
|
||||||
|
dnd_data = FilesClipFromUrisFree(gtk_selection_data_get_uris(data));
|
||||||
else
|
else
|
||||||
dnd_data = GtkDataGet(data);
|
dnd_data = GtkDataGet(data);
|
||||||
}
|
}
|
||||||
|
|
@ -227,9 +239,9 @@ String Ctrl::DragGet(const char *fmt)
|
||||||
dnd_data_fmt = fmt;
|
dnd_data_fmt = fmt;
|
||||||
int t0 = msecs();
|
int t0 = msecs();
|
||||||
gtk_drag_get_data(dnd_widget, dnd_context,
|
gtk_drag_get_data(dnd_widget, dnd_context,
|
||||||
GAtom(strcmp(fmt, "image") == 0 ? ~dnd_image_target
|
GAtom(strcmp(fmt, "image") == 0 ? ~dnd_image_target :
|
||||||
: strcmp(fmt, "text") == 0 ? ~dnd_text_target
|
strcmp(fmt, "text") == 0 ? ~dnd_text_target :
|
||||||
: fmt),
|
strcmp(fmt, "files") == 0 ? ~dnd_files_target : fmt),
|
||||||
dnd_time);
|
dnd_time);
|
||||||
while(msecs() - t0 < 1000 && dnd_data_wait)
|
while(msecs() - t0 < 1000 && dnd_data_wait)
|
||||||
FetchEvents(true);
|
FetchEvents(true);
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
NAMESPACE_UPP
|
NAMESPACE_UPP
|
||||||
|
|
||||||
#define LLOG(x) // DLOG(x)
|
#define LLOG(x) // DLOG(x)
|
||||||
#define LOG_EVENTS
|
//#define LOG_EVENTS _DBG_
|
||||||
|
|
||||||
bool Ctrl::EventMouseValid;
|
bool Ctrl::EventMouseValid;
|
||||||
Point Ctrl::EventMousePos;
|
Point Ctrl::EventMousePos;
|
||||||
|
|
@ -368,6 +368,7 @@ void Ctrl::Proc()
|
||||||
w->WhenClose();
|
w->WhenClose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
case GDK_FOCUS_CHANGE:
|
case GDK_FOCUS_CHANGE:
|
||||||
LLOG("FocusChange in: " << (bool)CurrentEvent.value << ", focusCtrlWnd " << focusCtrlWnd);
|
LLOG("FocusChange in: " << (bool)CurrentEvent.value << ", focusCtrlWnd " << focusCtrlWnd);
|
||||||
|
|
|
||||||
|
|
@ -197,6 +197,7 @@ bool TopWindow::IsTopMost() const
|
||||||
|
|
||||||
void TopWindow::GuiPlatformConstruct()
|
void TopWindow::GuiPlatformConstruct()
|
||||||
{
|
{
|
||||||
|
topmost = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TopWindow::GuiPlatformDestruct()
|
void TopWindow::GuiPlatformDestruct()
|
||||||
|
|
|
||||||
|
|
@ -98,14 +98,15 @@ GdkRect::GdkRect(const Rect& r)
|
||||||
height = r.GetHeight();
|
height = r.GetHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
Image ImageFromPixbufUnref(GdkPixbuf *pixbuf)
|
String ImageClipFromPixbufUnref(GdkPixbuf *pixbuf)
|
||||||
{
|
{
|
||||||
Image img;
|
Image img;
|
||||||
if(pixbuf) {
|
if(pixbuf) {
|
||||||
if(gdk_pixbuf_get_n_channels (pixbuf) == 4 &&
|
int chn = gdk_pixbuf_get_n_channels(pixbuf);
|
||||||
gdk_pixbuf_get_colorspace (pixbuf) == GDK_COLORSPACE_RGB &&
|
if((chn == 3 && !gdk_pixbuf_get_has_alpha(pixbuf) ||
|
||||||
gdk_pixbuf_get_bits_per_sample (pixbuf) == 8 &&
|
chn == 4 && gdk_pixbuf_get_has_alpha(pixbuf)) &&
|
||||||
gdk_pixbuf_get_has_alpha (pixbuf)) {
|
gdk_pixbuf_get_colorspace(pixbuf) == GDK_COLORSPACE_RGB &&
|
||||||
|
gdk_pixbuf_get_bits_per_sample(pixbuf) == 8) {
|
||||||
Size sz(gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height(pixbuf));
|
Size sz(gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height(pixbuf));
|
||||||
ImageBuffer m(sz);
|
ImageBuffer m(sz);
|
||||||
int stride = gdk_pixbuf_get_rowstride(pixbuf);
|
int stride = gdk_pixbuf_get_rowstride(pixbuf);
|
||||||
|
|
@ -114,6 +115,7 @@ Image ImageFromPixbufUnref(GdkPixbuf *pixbuf)
|
||||||
RGBA *s = m[y];
|
RGBA *s = m[y];
|
||||||
const RGBA *e = s + sz.cx;
|
const RGBA *e = s + sz.cx;
|
||||||
const byte *t = l;
|
const byte *t = l;
|
||||||
|
if(chn == 4)
|
||||||
while(s < e) {
|
while(s < e) {
|
||||||
s->r = *t++;
|
s->r = *t++;
|
||||||
s->g = *t++;
|
s->g = *t++;
|
||||||
|
|
@ -121,13 +123,33 @@ Image ImageFromPixbufUnref(GdkPixbuf *pixbuf)
|
||||||
s->a = *t++;
|
s->a = *t++;
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
while(s < e) {
|
||||||
|
s->r = *t++;
|
||||||
|
s->g = *t++;
|
||||||
|
s->b = *t++;
|
||||||
|
s->a = 255;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
l += stride;
|
l += stride;
|
||||||
}
|
}
|
||||||
img = m;
|
img = m;
|
||||||
}
|
}
|
||||||
g_object_unref(pixbuf);
|
g_object_unref(pixbuf);
|
||||||
}
|
}
|
||||||
return img;
|
return StoreAsString(img);
|
||||||
|
}
|
||||||
|
|
||||||
|
String FilesClipFromUrisFree(gchar **uris)
|
||||||
|
{
|
||||||
|
if(uris) {
|
||||||
|
String h;
|
||||||
|
for(int i = 0; uris[i]; i++)
|
||||||
|
h << uris[i] << '\n';
|
||||||
|
g_strfreev (uris);
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
return Null;
|
||||||
}
|
}
|
||||||
|
|
||||||
GdkAtom GAtom(const String& id)
|
GdkAtom GAtom(const String& id)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue