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();
|
||||
};
|
||||
|
||||
Image ImageFromPixbufUnref(GdkPixbuf *pixbuf);
|
||||
String FilesClipFromUrisFree(gchar **uris);
|
||||
String ImageClipFromPixbufUnref(GdkPixbuf *pixbuf);
|
||||
|
||||
GdkAtom GAtom(const String& id);
|
||||
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ String Ctrl::GtkDataGet(GtkSelectionData *s)
|
|||
|
||||
String Ctrl::Gclipboard::Get(const String& fmt)
|
||||
{
|
||||
LLOG("Ctrl::Gclipboard::Get " << fmt);
|
||||
if(fmt == "text") {
|
||||
gchar *s = gtk_clipboard_wait_for_text(clipboard);
|
||||
if(s) {
|
||||
|
|
@ -99,16 +100,19 @@ String Ctrl::Gclipboard::Get(const String& fmt)
|
|||
return Null;
|
||||
}
|
||||
else
|
||||
if(fmt == "image") {
|
||||
Image img = ImageFromPixbufUnref(gtk_clipboard_wait_for_image(clipboard));
|
||||
return StoreAsString(img); // Not very optimal...
|
||||
}
|
||||
if(fmt == "image")
|
||||
return ImageClipFromPixbufUnref(gtk_clipboard_wait_for_image(clipboard));
|
||||
else
|
||||
if(fmt == "files")
|
||||
return FilesClipFromUrisFree(gtk_clipboard_wait_for_uris(clipboard));
|
||||
else
|
||||
return GtkDataGet(gtk_clipboard_wait_for_contents(clipboard, GAtom(fmt)));
|
||||
}
|
||||
|
||||
bool Ctrl::Gclipboard::IsAvailable(const String& fmt)
|
||||
{
|
||||
if(fmt == "files")
|
||||
return gtk_clipboard_wait_is_uris_available(clipboard);
|
||||
if(fmt == "text")
|
||||
return gtk_clipboard_wait_is_text_available(clipboard);
|
||||
if(fmt == "image")
|
||||
|
|
@ -336,12 +340,20 @@ bool IsAvailableFiles(PasteClip& clip)
|
|||
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)
|
||||
{
|
||||
GuiLock __;
|
||||
Vector<String> f;
|
||||
return f;
|
||||
return GetClipFiles(clip.Get("files"));
|
||||
}
|
||||
|
||||
Ptr<Ctrl> Ctrl::sel_ctrl;
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@
|
|||
static Index<String> dnd_targets;
|
||||
static String dnd_text_target;
|
||||
static String dnd_image_target;
|
||||
static String dnd_files_target;
|
||||
static String dnd_data;
|
||||
static String dnd_data_fmt;
|
||||
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;
|
||||
String Ctrl::dnd_text_target;
|
||||
String Ctrl::dnd_image_target;
|
||||
String Ctrl::dnd_files_target;
|
||||
GtkWidget *Ctrl::dnd_widget;
|
||||
GdkDragContext *Ctrl::dnd_context;
|
||||
guint Ctrl::dnd_time;
|
||||
|
|
@ -161,13 +162,17 @@ void Ctrl::DndTargets(GdkDragContext *context)
|
|||
{
|
||||
static Index<String> text_targets;
|
||||
static Index<String> image_targets;
|
||||
static Index<String> files_targets;
|
||||
ONCELOCK {
|
||||
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);
|
||||
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);
|
||||
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_text_target.Clear();
|
||||
|
|
@ -184,6 +189,12 @@ void Ctrl::DndTargets(GdkDragContext *context)
|
|||
if(dnd_image_target.IsEmpty())
|
||||
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
|
||||
dnd_targets.Add(g);
|
||||
}
|
||||
|
|
@ -193,7 +204,7 @@ void Ctrl::GtkDragDataReceived(GtkWidget *widget, GdkDragContext *context,
|
|||
gint x, gint y, GtkSelectionData *data,
|
||||
guint info, guint time, gpointer user_data)
|
||||
{
|
||||
LLOG("GtkDragDataReceived");
|
||||
LLOG("GtkDragDataReceived " << dnd_data_fmt);
|
||||
dnd_data_wait = false;
|
||||
if(dnd_data_fmt == "text") {
|
||||
guchar *s = gtk_selection_data_get_text(data);
|
||||
|
|
@ -203,10 +214,11 @@ void Ctrl::GtkDragDataReceived(GtkWidget *widget, GdkDragContext *context,
|
|||
}
|
||||
}
|
||||
else
|
||||
if(dnd_data_fmt == "image") {
|
||||
Image img = ImageFromPixbufUnref(gtk_selection_data_get_pixbuf(data));
|
||||
dnd_data = StoreAsString(img); // Not very optimal...
|
||||
}
|
||||
if(dnd_data_fmt == "image")
|
||||
dnd_data = ImageClipFromPixbufUnref(gtk_selection_data_get_pixbuf(data));
|
||||
else
|
||||
if(dnd_data_fmt == "files")
|
||||
dnd_data = FilesClipFromUrisFree(gtk_selection_data_get_uris(data));
|
||||
else
|
||||
dnd_data = GtkDataGet(data);
|
||||
}
|
||||
|
|
@ -227,9 +239,9 @@ String Ctrl::DragGet(const char *fmt)
|
|||
dnd_data_fmt = fmt;
|
||||
int t0 = msecs();
|
||||
gtk_drag_get_data(dnd_widget, dnd_context,
|
||||
GAtom(strcmp(fmt, "image") == 0 ? ~dnd_image_target
|
||||
: strcmp(fmt, "text") == 0 ? ~dnd_text_target
|
||||
: fmt),
|
||||
GAtom(strcmp(fmt, "image") == 0 ? ~dnd_image_target :
|
||||
strcmp(fmt, "text") == 0 ? ~dnd_text_target :
|
||||
strcmp(fmt, "files") == 0 ? ~dnd_files_target : fmt),
|
||||
dnd_time);
|
||||
while(msecs() - t0 < 1000 && dnd_data_wait)
|
||||
FetchEvents(true);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) // DLOG(x)
|
||||
#define LOG_EVENTS
|
||||
//#define LOG_EVENTS _DBG_
|
||||
|
||||
bool Ctrl::EventMouseValid;
|
||||
Point Ctrl::EventMousePos;
|
||||
|
|
@ -368,6 +368,7 @@ void Ctrl::Proc()
|
|||
w->WhenClose();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
case GDK_FOCUS_CHANGE:
|
||||
LLOG("FocusChange in: " << (bool)CurrentEvent.value << ", focusCtrlWnd " << focusCtrlWnd);
|
||||
|
|
|
|||
|
|
@ -197,6 +197,7 @@ bool TopWindow::IsTopMost() const
|
|||
|
||||
void TopWindow::GuiPlatformConstruct()
|
||||
{
|
||||
topmost = false;
|
||||
}
|
||||
|
||||
void TopWindow::GuiPlatformDestruct()
|
||||
|
|
|
|||
|
|
@ -98,14 +98,15 @@ GdkRect::GdkRect(const Rect& r)
|
|||
height = r.GetHeight();
|
||||
}
|
||||
|
||||
Image ImageFromPixbufUnref(GdkPixbuf *pixbuf)
|
||||
String ImageClipFromPixbufUnref(GdkPixbuf *pixbuf)
|
||||
{
|
||||
Image img;
|
||||
if(pixbuf) {
|
||||
if(gdk_pixbuf_get_n_channels (pixbuf) == 4 &&
|
||||
gdk_pixbuf_get_colorspace (pixbuf) == GDK_COLORSPACE_RGB &&
|
||||
gdk_pixbuf_get_bits_per_sample (pixbuf) == 8 &&
|
||||
gdk_pixbuf_get_has_alpha (pixbuf)) {
|
||||
int chn = gdk_pixbuf_get_n_channels(pixbuf);
|
||||
if((chn == 3 && !gdk_pixbuf_get_has_alpha(pixbuf) ||
|
||||
chn == 4 && 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));
|
||||
ImageBuffer m(sz);
|
||||
int stride = gdk_pixbuf_get_rowstride(pixbuf);
|
||||
|
|
@ -114,6 +115,7 @@ Image ImageFromPixbufUnref(GdkPixbuf *pixbuf)
|
|||
RGBA *s = m[y];
|
||||
const RGBA *e = s + sz.cx;
|
||||
const byte *t = l;
|
||||
if(chn == 4)
|
||||
while(s < e) {
|
||||
s->r = *t++;
|
||||
s->g = *t++;
|
||||
|
|
@ -121,13 +123,33 @@ Image ImageFromPixbufUnref(GdkPixbuf *pixbuf)
|
|||
s->a = *t++;
|
||||
s++;
|
||||
}
|
||||
else
|
||||
while(s < e) {
|
||||
s->r = *t++;
|
||||
s->g = *t++;
|
||||
s->b = *t++;
|
||||
s->a = 255;
|
||||
s++;
|
||||
}
|
||||
l += stride;
|
||||
}
|
||||
img = m;
|
||||
}
|
||||
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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue