void DiffSideBySidePanel::OnCopyRightToLeft(wxRibbonButtonBarEvent& event)
{
    bool moveToNext = m_config.GetFlags() & DiffConfig::kCopyRightToLeftAndMove;
    DoCopyCurrentSequence(m_stcRight, m_stcLeft);
    if(moveToNext && CanNextDiff()) {
        wxRibbonButtonBarEvent dummy;
        OnNextDiffSequence(dummy);
    }
}
void DiffSideBySidePanel::OnCopyLeftToRight(wxCommandEvent& event)
{
    bool moveToNext = /*m_config.GetFlags() & DiffConfig::kCopyLeftToRightAndMove*/ true;
    DoCopyCurrentSequence(m_stcLeft, m_stcRight);
    if(moveToNext && CanNextDiff()) {
        wxCommandEvent dummy;
        OnNextDiffSequence(dummy);
    }
}
void DiffSideBySidePanel::Diff()
{
    wxFileName fnLeft(m_filePickerLeft->GetPath());
    wxFileName fnRIght(m_filePickerRight->GetPath());

    if(!fnLeft.Exists()) {
        ::wxMessageBox(wxString() << _("Left Side File:\n") << fnLeft.GetFullPath() << _(" does not exist!"),
                       "CodeLite",
                       wxICON_ERROR | wxCENTER | wxOK);
        return;
    }

    if(!fnRIght.Exists()) {
        ::wxMessageBox(wxString() << _("Right Side File:\n") << fnRIght.GetFullPath() << _(" does not exist!"),
                       "CodeLite",
                       wxICON_ERROR | wxCENTER | wxOK);
        return;
    }

    // Cleanup
    DoClean();

    // Prepare the views
    PrepareViews();

    // Prepare the diff
    clDTL d;
    d.Diff(m_filePickerLeft->GetPath(),
           m_filePickerRight->GetPath(),
           m_config.IsSingleViewMode() ? clDTL::kOnePane : clDTL::kTwoPanes);
    const clDTL::LineInfoVec_t& resultLeft = d.GetResultLeft();
    const clDTL::LineInfoVec_t& resultRight = d.GetResultRight();
    m_sequences = d.GetSequences();

    if(m_sequences.empty()) {
        // Files are the same !
        m_stcLeft->SetReadOnly(false);
        m_stcRight->SetReadOnly(false);

        m_stcLeft->LoadFile(fnLeft.GetFullPath());
        m_stcRight->LoadFile(fnRIght.GetFullPath());

        m_stcLeft->SetSavePoint();
        m_stcRight->SetSavePoint();

        m_stcLeft->SetReadOnly(true);
        m_stcRight->SetReadOnly(true);
        return;
    }

    m_cur_sequence = 0; // the first line of the sequence

    // Create 2 strings "left" and "right"
    wxString leftContent, rightContent;

    // The left pane is always the one with the deletions "-"
    for(size_t i = 0; i < resultLeft.size(); ++i) {
        if(resultLeft.at(i).m_type == clDTL::LINE_ADDED) {
            leftContent << resultLeft.at(i).m_line;
            m_leftGreenMarkers.push_back(i);

        } else if(resultLeft.at(i).m_type == clDTL::LINE_REMOVED) {
            leftContent << resultLeft.at(i).m_line;
            m_leftRedMarkers.push_back(i);

        } else if(resultLeft.at(i).m_type == clDTL::LINE_PLACEHOLDER) {
            // PLACEHOLDER
            leftContent << resultLeft.at(i).m_line;
            m_leftPlaceholdersMarkers.push_back(i);

        } else {
            // COMMON
            leftContent << resultLeft.at(i).m_line;
        }
    }

    // The right pane is always with the new additions "+"
    for(size_t i = 0; i < resultRight.size(); ++i) {
        if(resultRight.at(i).m_type == clDTL::LINE_REMOVED) {
            rightContent << resultRight.at(i).m_line;
            m_rightRedMarkers.push_back(i);

        } else if(resultRight.at(i).m_type == clDTL::LINE_ADDED) {
            rightContent << resultRight.at(i).m_line;
            m_rightGreenMarkers.push_back(i);

        } else if(resultRight.at(i).m_type == clDTL::LINE_PLACEHOLDER) {
            rightContent << resultRight.at(i).m_line;
            m_rightPlaceholdersMarkers.push_back(i);

        } else {
            // COMMON
            rightContent << resultRight.at(i).m_line;
        }
    }
    UpdateViews(leftContent, rightContent);
    m_stcLeft->SetSavePoint();
    m_stcRight->SetSavePoint();

    // Select the first diff
    wxRibbonButtonBarEvent dummy;
    m_cur_sequence = -1;
    OnNextDiffSequence(dummy);
}