示例#1
0
文件: dnd.cpp 项目: madnessw/thesnow
static gint
gtk_dnd_window_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *WXUNUSED(event), wxDropSource *source )
{
    source->GiveFeedback( ConvertFromGTK(source->m_dragContext->action) );

    return 0;
}
示例#2
0
wxDragResult wxDropTarget::GTKFigureOutSuggestedAction()
{
    if (!m_dragContext)
        return wxDragError;

    // GTK+ always supposes that we want to copy the data by default while we
    // might want to move it, so examine not only suggested_action - which is
    // only good if we don't have our own preferences - but also the actions
    // field
    wxDragResult suggested_action = wxDragNone;
    const GdkDragAction actions = gdk_drag_context_get_actions(m_dragContext);
    if (GetDefaultAction() == wxDragNone)
    {
        // use default action set by wxDropSource::DoDragDrop()
        if ( (gs_flagsForDrag & wxDrag_DefaultMove) == wxDrag_DefaultMove &&
            (actions & GDK_ACTION_MOVE))
        {
            // move is requested by the program and allowed by GTK+ - do it, even
            // though suggested_action may be currently wxDragCopy
            suggested_action = wxDragMove;
        }
        else // use whatever GTK+ says we should
        {
            suggested_action = ConvertFromGTK(gdk_drag_context_get_suggested_action(m_dragContext));

#if 0
            // RR: I don't understand the code below: if the drag comes from
            //     a different app, the gs_flagsForDrag is invalid; if it
            //     comes from the same wx app, then GTK+ hopefully won't
            //     suggest something we didn't allow in the frist place
            //     in DoDrop()
            if ( (suggested_action == wxDragMove) && !(gs_flagsForDrag & wxDrag_AllowMove) )
            {
                // we're requested to move but we can't
                suggested_action = wxDragCopy;
            }
#endif
        }
    }
    else if (GetDefaultAction() == wxDragMove &&
            (actions & GDK_ACTION_MOVE))
    {

        suggested_action = wxDragMove;
    }
    else
    {
        if (actions & GDK_ACTION_COPY)
            suggested_action = wxDragCopy;
        else if (actions & GDK_ACTION_MOVE)
            suggested_action = wxDragMove;
        else if (actions & GDK_ACTION_LINK)
            suggested_action = wxDragLink;
        else
            suggested_action = wxDragNone;
    }

    return suggested_action;
}
示例#3
0
static gint
gtk_dnd_window_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *WXUNUSED(event), wxDropSource *source )
{
    // don't need to install idle handler, its done from "event" signal

    source->GiveFeedback( ConvertFromGTK(source->m_dragContext->action) );

    return 0;
}
示例#4
0
文件: dnd.cpp 项目: madnessw/thesnow
static void
source_drag_data_get  (GtkWidget          *WXUNUSED(widget),
                       GdkDragContext     *context,
                       GtkSelectionData   *selection_data,
                       guint               WXUNUSED(info),
                       guint               WXUNUSED(time),
                       wxDropSource       *drop_source )
{
    wxDataFormat format( selection_data->target );

    wxLogTrace(TRACE_DND, wxT("Drop source: format requested: %s"),
               format.GetId().c_str());

    drop_source->m_retValue = wxDragError;

    wxDataObject *data = drop_source->GetDataObject();

    if (!data)
    {
        wxLogTrace(TRACE_DND, wxT("Drop source: no data object") );
        return;
    }

    if (!data->IsSupportedFormat(format))
    {
        wxLogTrace(TRACE_DND, wxT("Drop source: unsupported format") );
        return;
    }

    if (data->GetDataSize(format) == 0)
    {
        wxLogTrace(TRACE_DND, wxT("Drop source: empty data") );
        return;
    }

    size_t size = data->GetDataSize(format);

//  printf( "data size: %d.\n", (int)data_size );

    guchar *d = new guchar[size];

    if (!data->GetDataHere( format, (void*)d ))
    {
        delete[] d;
        return;
    }

    drop_source->m_retValue = ConvertFromGTK( context->action );

    gtk_selection_data_set( selection_data,
                            selection_data->target,
                            8,   // 8-bit
                            d,
                            size );

    delete[] d;
}
示例#5
0
    static gint
    gtk_dnd_window_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *WXUNUSED(event), wxDropSource *source )
    {
        if (g_isIdle)
            wxapp_install_idle_handler();

        source->GiveFeedback( ConvertFromGTK(source->m_dragContext->action) );

        return 0;
    }
示例#6
0
static void target_drag_data_received( GtkWidget *WXUNUSED(widget),
                                       GdkDragContext *context,
                                       gint x,
                                       gint y,
                                       GtkSelectionData *data,
                                       guint WXUNUSED(info),
                                       guint time,
                                       wxDropTarget *drop_target )
{
    if (g_isIdle) wxapp_install_idle_handler();

    /* Owen Taylor: "call gtk_drag_finish() with
       success == TRUE" */

    if ((data->length <= 0) || (data->format != 8))
    {
        /* negative data length and non 8-bit data format
           qualifies for junk */
        gtk_drag_finish (context, FALSE, FALSE, time);

        return;
    }

#ifdef __WXDEBUG__
    wxLogTrace(TRACE_DND, wxT( "Drop target: data received event") );
#endif
   
    /* inform the wxDropTarget about the current GtkSelectionData.
       this is only valid for the duration of this call */
    drop_target->SetDragData( data );

    wxDragResult result = ConvertFromGTK(context->action);

    if ( wxIsDragResultOk( drop_target->OnData( x, y, result ) ) )
    {
#ifdef __WXDEBUG__
        wxLogTrace(TRACE_DND, wxT( "Drop target: OnData returned true") );
#endif
       
        /* tell GTK that data transfer was successful */
        gtk_drag_finish( context, TRUE, FALSE, time );
    }
    else
    {
#ifdef __WXDEBUG__
        wxLogTrace(TRACE_DND, wxT( "Drop target: OnData returned FALSE") );
#endif
       
        /* tell GTK that data transfer was not successful */
        gtk_drag_finish( context, FALSE, FALSE, time );
    }

    /* after this, invalidate the drop_target's drag data */
    drop_target->SetDragData( (GtkSelectionData*) NULL );
}
示例#7
0
static void target_drag_data_received( GtkWidget *WXUNUSED(widget),
                                       GdkDragContext *context,
                                       gint x,
                                       gint y,
                                       GtkSelectionData *data,
                                       guint WXUNUSED(info),
                                       guint time,
                                       wxDropTarget *drop_target )
{
    /* Owen Taylor: "call gtk_drag_finish() with
       success == TRUE" */

    if (gtk_selection_data_get_length(data) <= 0 || gtk_selection_data_get_format(data) != 8)
    {
        /* negative data length and non 8-bit data format
           qualifies for junk */
        gtk_drag_finish (context, FALSE, FALSE, time);

        return;
    }

    wxLogTrace(TRACE_DND, wxT( "Drop target: data received event") );

    /* inform the wxDropTarget about the current GtkSelectionData.
       this is only valid for the duration of this call */
    drop_target->GTKSetDragData( data );

    wxDragResult result = ConvertFromGTK(gdk_drag_context_get_selected_action(context));

    if ( wxIsDragResultOk( drop_target->OnData( x, y, result ) ) )
    {
        wxLogTrace(TRACE_DND, wxT( "Drop target: OnData returned true") );

        /* tell GTK that data transfer was successful */
        gtk_drag_finish( context, TRUE, FALSE, time );
    }
    else
    {
        wxLogTrace(TRACE_DND, wxT( "Drop target: OnData returned FALSE") );

        /* tell GTK that data transfer was not successful */
        gtk_drag_finish( context, FALSE, FALSE, time );
    }

    /* after this, invalidate the drop_target's drag data */
    drop_target->GTKSetDragData( NULL );
}
示例#8
0
wxDragResult wxDropSource::DoDragDrop(int flags)
{
    wxCHECK_MSG( m_data && m_data->GetFormatCount(), wxDragNone,
                 wxT("Drop source: no data") );

    // still in drag
    if (g_blockEventsOnDrag)
        return wxDragNone;

    // don't start dragging if no button is down
    if (g_lastButtonNumber == 0)
        return wxDragNone;
        
    // we can only start a drag after a mouse event
    if (g_lastMouseEvent == NULL)
        return wxDragNone;

    // disabled for now
    g_blockEventsOnDrag = true;

    RegisterWindow();

    m_waiting = true;

    GtkTargetList *target_list = gtk_target_list_new( (GtkTargetEntry*) NULL, 0 );

    wxDataFormat *array = new wxDataFormat[ m_data->GetFormatCount() ];
    m_data->GetAllFormats( array );
    size_t count = m_data->GetFormatCount();
    for (size_t i = 0; i < count; i++)
    {
        GdkAtom atom = array[i];
#ifdef __WXDEBUG__
        wxLogTrace(TRACE_DND, wxT("Drop source: Supported atom %s"), gdk_atom_name( atom ));
#endif
       gtk_target_list_add( target_list, atom, 0, 0 );
    }
    delete[] array;

    int action = GDK_ACTION_COPY;
    if ( flags & wxDrag_AllowMove )
        action |= GDK_ACTION_MOVE;

    // VZ: as we already use g_blockEventsOnDrag it shouldn't be that bad
    //     to use a global to pass the flags to the drop target but I'd
    //     surely prefer a better way to do it
    gs_flagsForDrag = flags;

    GdkDragContext *context = gtk_drag_begin( m_widget,
                target_list,
                (GdkDragAction)action,
                g_lastButtonNumber,  // number of mouse button which started drag
                (GdkEvent*) g_lastMouseEvent );

    m_dragContext = context;

    PrepareIcon( action, context );

    while (m_waiting)
        gtk_main_iteration();

    m_retValue = ConvertFromGTK(context->action);
    if ( m_retValue == wxDragNone )
         m_retValue = wxDragCancel;

    g_blockEventsOnDrag = false;

    UnregisterWindow();

    return m_retValue;
}
示例#9
0
static gboolean target_drag_motion( GtkWidget *WXUNUSED(widget),
                                    GdkDragContext *context,
                                    gint x,
                                    gint y,
                                    guint time,
                                    wxDropTarget *drop_target )
{
    if (g_isIdle) wxapp_install_idle_handler();

    /* Owen Taylor: "if the coordinates not in a drop zone,
       return FALSE, otherwise call gtk_drag_status() and
       return TRUE" */

    /* inform the wxDropTarget about the current GdkDragContext.
       this is only valid for the duration of this call */
    drop_target->SetDragContext( context );

    // GTK+ always supposes that we want to copy the data by default while we
    // might want to move it, so examine not only suggested_action - which is
    // only good if we don't have our own preferences - but also the actions
    // field
    wxDragResult result;
    if (drop_target->GetDefaultAction() == wxDragNone)
    {
        // use default action set by wxDropSource::DoDragDrop()
    if ( (gs_flagsForDrag & wxDrag_DefaultMove) == wxDrag_DefaultMove &&
            (context->actions & GDK_ACTION_MOVE ) )
    {
        // move is requested by the program and allowed by GTK+ - do it, even
        // though suggested_action may be currently wxDragCopy
        result = wxDragMove;
    }
    else // use whatever GTK+ says we should
    {
        result = ConvertFromGTK(context->suggested_action);

        if ( (result == wxDragMove) && !(gs_flagsForDrag & wxDrag_AllowMove) )
        {
            // we're requested to move but we can't
            result = wxDragCopy;
        }
    }
    }
    else if (drop_target->GetDefaultAction() == wxDragMove &&
                (context->actions & GDK_ACTION_MOVE))
    {
       result = wxDragMove;
    }
    else
    {
        if (context->actions & GDK_ACTION_COPY)
            result = wxDragCopy;
        else if (context->actions & GDK_ACTION_MOVE)
            result = wxDragMove;
        else
            result = wxDragNone;
    }

    if (drop_target->m_firstMotion)
    {
        /* the first "drag_motion" event substitutes a "drag_enter" event */
        result = drop_target->OnEnter( x, y, result );
    }
    else
    {
        /* give program a chance to react (i.e. to say no by returning FALSE) */
        result = drop_target->OnDragOver( x, y, result );
    }

    bool ret = wxIsDragResultOk( result );
    if (ret)
    {
        GdkDragAction action;
        if (result == wxDragCopy)
            action = GDK_ACTION_COPY;
        else if (result == wxDragLink)
            action = GDK_ACTION_LINK;
        else
            action = GDK_ACTION_MOVE;

        gdk_drag_status( context, action, time );
    }

    /* after this, invalidate the drop_target's GdkDragContext */
    drop_target->SetDragContext( (GdkDragContext*) NULL );

    /* this has to be done because GDK has no "drag_enter" event */
    drop_target->m_firstMotion = false;

    return ret;
}