looks like the pasting works, untested though
This commit is contained in:
parent
260a4f5f65
commit
9e252566c6
|
@ -24,6 +24,18 @@
|
|||
|
||||
#include "actionUtil.h"
|
||||
|
||||
static const char* text_format_headers[] =
|
||||
{
|
||||
"ModPlug Tracker MOD",
|
||||
"ModPlug Tracker S3M",
|
||||
"ModPlug Tracker XM",
|
||||
"ModPlug Tracker XM",
|
||||
"ModPlug Tracker IT",
|
||||
"ModPlug Tracker IT",
|
||||
"ModPlug Tracker MPT",
|
||||
NULL,
|
||||
};
|
||||
|
||||
const char* FurnaceGUI::noteNameNormal(short note, short octave) {
|
||||
if (note==100) { // note cut
|
||||
return "OFF";
|
||||
|
@ -433,36 +445,8 @@ String FurnaceGUI::doCopy(bool cut, bool writeClipboard, const SelectionPoint& s
|
|||
return clipb;
|
||||
}
|
||||
|
||||
void FurnaceGUI::doPaste(PasteMode mode, int arg, bool readClipboard, String clipb) {
|
||||
if (readClipboard) {
|
||||
finishSelection();
|
||||
prepareUndo(GUI_UNDO_PATTERN_PASTE);
|
||||
char* clipText=SDL_GetClipboardText();
|
||||
if (clipText!=NULL) {
|
||||
if (clipText[0]) {
|
||||
clipboard=clipText;
|
||||
}
|
||||
SDL_free(clipText);
|
||||
}
|
||||
clipb=clipboard;
|
||||
}
|
||||
std::vector<String> data;
|
||||
String tempS;
|
||||
for (char i: clipb) {
|
||||
if (i=='\r') continue;
|
||||
if (i=='\n') {
|
||||
data.push_back(tempS);
|
||||
tempS="";
|
||||
continue;
|
||||
}
|
||||
tempS+=i;
|
||||
}
|
||||
data.push_back(tempS);
|
||||
|
||||
int startOff=-1;
|
||||
bool invalidData=false;
|
||||
if (data.size()<2) return;
|
||||
if (data[0].find("org.tildearrow.furnace - Pattern Data")!=0) return;
|
||||
void FurnaceGUI::doPasteFurnace(PasteMode mode, int arg, bool readClipboard, String clipb, std::vector<String> data, int startOff, bool invalidData)
|
||||
{
|
||||
if (sscanf(data[1].c_str(),"%d",&startOff)!=1) return;
|
||||
if (startOff<0) return;
|
||||
|
||||
|
@ -513,7 +497,7 @@ void FurnaceGUI::doPaste(PasteMode mode, int arg, bool readClipboard, String cli
|
|||
}
|
||||
|
||||
if ((mode==GUI_PASTE_MODE_MIX_BG || mode==GUI_PASTE_MODE_MIX_FG ||
|
||||
mode==GUI_PASTE_MODE_INS_BG || mode==GUI_PASTE_MODE_INS_FG) && strcmp(note,"...")==0) {
|
||||
mode==GUI_PASTE_MODE_INS_BG || mode==GUI_PASTE_MODE_INS_FG) && strcmp(note,"...")==0) {
|
||||
// do nothing.
|
||||
} else {
|
||||
if (!(mode==GUI_PASTE_MODE_MIX_BG || mode==GUI_PASTE_MODE_INS_BG) || (pat->data[j][0]==0 && pat->data[j][1]==0)) {
|
||||
|
@ -607,6 +591,785 @@ void FurnaceGUI::doPaste(PasteMode mode, int arg, bool readClipboard, String cli
|
|||
}
|
||||
}
|
||||
|
||||
uint64_t convert_effect_openmpt_mod(char symbol, uint16_t val)
|
||||
{
|
||||
switch(symbol)
|
||||
{
|
||||
case '0':
|
||||
{
|
||||
return ((0x00) << 8) | (val);
|
||||
break;
|
||||
}
|
||||
|
||||
case '1':
|
||||
{
|
||||
return ((0x01) << 8) | (val);
|
||||
break;
|
||||
}
|
||||
|
||||
case '2':
|
||||
{
|
||||
return ((0x02) << 8) | (val);
|
||||
break;
|
||||
}
|
||||
|
||||
case '3':
|
||||
{
|
||||
return ((0x03) << 8) | (val);
|
||||
break;
|
||||
}
|
||||
|
||||
case '4':
|
||||
{
|
||||
return ((0x04) << 8) | (val);
|
||||
break;
|
||||
}
|
||||
|
||||
case '5':
|
||||
{
|
||||
return ((0x0a) << 8) | (val) | ((0x03) << 24); //Axy + 300
|
||||
break;
|
||||
}
|
||||
|
||||
case '6':
|
||||
{
|
||||
return ((0x0a) << 8) | (val) | ((0x04) << 24); //Axy + 400
|
||||
break;
|
||||
}
|
||||
|
||||
case '7':
|
||||
{
|
||||
return ((0x07) << 8) | (val);
|
||||
break;
|
||||
}
|
||||
|
||||
case '8':
|
||||
{
|
||||
return ((0x80) << 8) | (val);
|
||||
break;
|
||||
}
|
||||
|
||||
case '9':
|
||||
{
|
||||
return ((0x90) << 8) | (val);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'A':
|
||||
{
|
||||
return ((0x0A) << 8) | (val);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'B':
|
||||
{
|
||||
return ((0x0B) << 8) | (val);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'C':
|
||||
{
|
||||
return ((0x0C) << 8) | (val); //interpreted as volume later
|
||||
break;
|
||||
}
|
||||
|
||||
case 'D':
|
||||
{
|
||||
uint8_t new_param = (val & 0xf) + ((val & 0xff) >> 4) * 10; //hex to decimal, Protracker (and XM too!) lol
|
||||
return ((0x0D) << 8) | (new_param);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'E':
|
||||
{
|
||||
switch(val >> 4)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
return ((0xF1) << 8) | (val & 0xf);
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
return ((0xF2) << 8) | (val & 0xf);
|
||||
break;
|
||||
}
|
||||
|
||||
//glissando and vib shape not supported in Furnace
|
||||
|
||||
case 5:
|
||||
{
|
||||
return ((0xF5) << 8) | ((val & 0xf) << 4);
|
||||
break;
|
||||
}
|
||||
|
||||
//pattern loop not supported
|
||||
|
||||
case 8:
|
||||
{
|
||||
return ((0x80) << 8) | ((val & 0xf) << 4);
|
||||
break;
|
||||
}
|
||||
|
||||
case 9:
|
||||
{
|
||||
return ((0x0C) << 8) | (val & 0xf);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0xA:
|
||||
{
|
||||
return ((0xF3) << 8) | (val & 0xf);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0xB:
|
||||
{
|
||||
return ((0xF4) << 8) | (val & 0xf);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0xC:
|
||||
{
|
||||
return ((0xFC) << 8) | (val & 0xf);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0xD:
|
||||
{
|
||||
return ((0xFD) << 8) | (val & 0xf);
|
||||
break;
|
||||
}
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
case 'F':
|
||||
{
|
||||
if(val < 0x20)
|
||||
{
|
||||
return ((0x09) << 8) | (val);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
return ((0xF0) << 8) | (val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t convert_effect_openmpt_s3m(char symbol, uint16_t val)
|
||||
{
|
||||
switch(symbol)
|
||||
{
|
||||
case 'A':
|
||||
{
|
||||
return ((0x09) << 8) | (val);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'B':
|
||||
{
|
||||
return ((0x0B) << 8) | (val);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'C':
|
||||
{
|
||||
return ((0x0D) << 8) | (val);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'D': //who the fuck invented this...
|
||||
{
|
||||
if((val & 0xf0) == 0xf0)
|
||||
{
|
||||
return ((0xF4) << 8) | (val & 0xf);
|
||||
}
|
||||
|
||||
else if((val & 0xf) == 0xf)
|
||||
{
|
||||
return ((0xF3) << 8) | ((val & 0xf0) >> 4);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
return ((0x0A) << 8) | val;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'E': //who the fuck invented this...
|
||||
{
|
||||
if(val < 0xe0)
|
||||
{
|
||||
return ((0x02) << 8) | val;
|
||||
}
|
||||
|
||||
else if(val >= 0xe0 && val < 0xf0)
|
||||
{
|
||||
return ((0xF2) << 8) | (val & 0xf);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
return ((0xF2) << 8) | ((val & 0xf) / 2);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'F': //who the fuck invented this...
|
||||
{
|
||||
if(val < 0xe0)
|
||||
{
|
||||
return ((0x01) << 8) | val;
|
||||
}
|
||||
|
||||
else if(val >= 0xe0 && val < 0xf0)
|
||||
{
|
||||
return ((0xF1) << 8) | (val & 0xf);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
return ((0xF1) << 8) | ((val & 0xf) / 2);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'G':
|
||||
{
|
||||
return ((0x03) << 8) | (val);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'H':
|
||||
{
|
||||
return ((0x04) << 8) | (val);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'J':
|
||||
{
|
||||
return ((0x00) << 8) | (val);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'K':
|
||||
{
|
||||
return ((0x0a) << 8) | (val) | ((0x04) << 24); //Axy + 400
|
||||
break;
|
||||
}
|
||||
|
||||
case 'L':
|
||||
{
|
||||
return ((0x0a) << 8) | (val) | ((0x03) << 24); //Axy + 300
|
||||
break;
|
||||
}
|
||||
|
||||
case 'O':
|
||||
{
|
||||
return ((0x90) << 8) | (val);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'Q':
|
||||
{
|
||||
return ((0xC0) << 8) | (val & 0xf);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'R':
|
||||
{
|
||||
return ((0x07) << 8) | (val & 0xf);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'S':
|
||||
{
|
||||
switch(val >> 4)
|
||||
{
|
||||
case 2:
|
||||
{
|
||||
return ((0xE5) << 8) | ((val & 0xf) << 4);
|
||||
break;
|
||||
}
|
||||
|
||||
case 8:
|
||||
{
|
||||
return ((0x80) << 8) | ((val & 0xf) << 4);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0xC:
|
||||
{
|
||||
return ((0xFC) << 8) | (val & 0xf);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0xD:
|
||||
{
|
||||
return ((0xFD) << 8) | (val & 0xf);
|
||||
break;
|
||||
}
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
case 'T':
|
||||
{
|
||||
return ((0xF0) << 8) | (val & 0xf);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'U':
|
||||
{
|
||||
return ((0x04) << 8) | MAX(1, ((val & 0xf0) >> 4 / 4 << 4)) | MAX(1, ((val & 0xf) / 4));
|
||||
break;
|
||||
}
|
||||
|
||||
case 'X':
|
||||
{
|
||||
return ((0x80) << 8) | (val);
|
||||
break;
|
||||
}
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t convert_effect_openmpt_xm(char symbol, uint16_t val)
|
||||
{
|
||||
return convert_effect_openmpt_mod(symbol, val);
|
||||
//other effects too obscure bruh
|
||||
}
|
||||
|
||||
uint64_t convert_effect_openmpt_it(char symbol, uint16_t val)
|
||||
{
|
||||
return convert_effect_openmpt_s3m(symbol, val);
|
||||
//other effects too obscure bruh
|
||||
}
|
||||
|
||||
uint64_t convert_effect_openmpt_mptm(char symbol, uint16_t val)
|
||||
{
|
||||
if(symbol == ':')
|
||||
{
|
||||
logW("dshit %d", ((val & 0xf0) >> 4));
|
||||
return ((0xED) << 8) | ((val & 0xf0) >> 4) | ((0xEC) << 24) | ((((val & 0xf0) >> 4) + (val & 0xf)) << 16);
|
||||
}
|
||||
|
||||
return convert_effect_openmpt_it(symbol, val);
|
||||
}
|
||||
|
||||
void FurnaceGUI::doPasteOpenMPT(PasteMode mode, int arg, bool readClipboard, String clipb, std::vector<String> data, int openmpt_format)
|
||||
{
|
||||
DETERMINE_LAST;
|
||||
|
||||
int j=cursor.y;
|
||||
char note[4];
|
||||
bool invalidData = true;
|
||||
|
||||
for(size_t i=1; i<data.size() && j<e->curSubSong->patLen; i++)
|
||||
{
|
||||
size_t charPos=1;
|
||||
int iCoarse=cursor.xCoarse;
|
||||
int iFine=0;
|
||||
|
||||
String& line=data[i];
|
||||
|
||||
while (charPos<line.size() && iCoarse<lastChannel)
|
||||
{
|
||||
DivPattern* pat=e->curPat[iCoarse].getPattern(e->curOrders->ord[iCoarse][curOrder],true);
|
||||
if (line[charPos]=='|' && charPos != 0) //OpenMPT format starts every pattern line with '|'
|
||||
{
|
||||
iCoarse++;
|
||||
|
||||
if (iCoarse<lastChannel) while (!e->curSubSong->chanShow[iCoarse])
|
||||
{
|
||||
iCoarse++;
|
||||
if (iCoarse>=lastChannel) break;
|
||||
}
|
||||
|
||||
iFine=0;
|
||||
charPos++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (iFine==0) //note
|
||||
{
|
||||
if (charPos>=line.size())
|
||||
{
|
||||
invalidData=true;
|
||||
break;
|
||||
}
|
||||
note[0]=line[charPos++];
|
||||
if (charPos>=line.size()) {
|
||||
invalidData=true;
|
||||
break;
|
||||
}
|
||||
note[1]=line[charPos++];
|
||||
if (charPos>=line.size()) {
|
||||
invalidData=true;
|
||||
break;
|
||||
}
|
||||
note[2]=line[charPos++];
|
||||
note[3]=0;
|
||||
|
||||
logW("note \"%s\"", note);
|
||||
|
||||
if (iFine==0 && !opMaskPaste.note) {
|
||||
iFine++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(note,"...")==0 || strcmp(note," ")==0)
|
||||
{
|
||||
// do nothing.
|
||||
|
||||
logW("note empty");
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if (!(mode==GUI_PASTE_MODE_MIX_BG || mode==GUI_PASTE_MODE_INS_BG) || (pat->data[j][0]==0 && pat->data[j][1]==0))
|
||||
{
|
||||
if (!decodeNote(note,pat->data[j][0],pat->data[j][1]))
|
||||
{
|
||||
invalidData=true;
|
||||
break;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
pat->data[j][1]--; //OpenMPT is one octave higher...
|
||||
}
|
||||
|
||||
if (mode==GUI_PASTE_MODE_INS_BG || mode==GUI_PASTE_MODE_INS_FG) pat->data[j][2]=arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (iFine==1) //instrument
|
||||
{
|
||||
if (charPos>=line.size())
|
||||
{
|
||||
invalidData=true;
|
||||
break;
|
||||
}
|
||||
note[0]=line[charPos++];
|
||||
if (charPos>=line.size())
|
||||
{
|
||||
invalidData=true;
|
||||
break;
|
||||
}
|
||||
note[1]=line[charPos++];
|
||||
note[2]=0;
|
||||
|
||||
logW("ins \"%s\"", note);
|
||||
|
||||
if (iFine==1)
|
||||
{
|
||||
if (!opMaskPaste.ins || mode==GUI_PASTE_MODE_INS_BG || mode==GUI_PASTE_MODE_INS_FG)
|
||||
{
|
||||
iFine++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp(note,"..")==0 || strcmp(note," ")==0)
|
||||
{
|
||||
if (!(mode==GUI_PASTE_MODE_MIX_BG || mode==GUI_PASTE_MODE_MIX_FG ||
|
||||
mode==GUI_PASTE_MODE_INS_BG || mode==GUI_PASTE_MODE_INS_FG))
|
||||
{
|
||||
pat->data[j][iFine+1]=-1;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
unsigned int val=0;
|
||||
if (sscanf(note,"%2X",&val)!=1)
|
||||
{
|
||||
invalidData=true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(mode==GUI_PASTE_MODE_MIX_BG || mode==GUI_PASTE_MODE_INS_BG) || pat->data[j][iFine+1]==-1)
|
||||
{
|
||||
pat->data[j][iFine+1]=val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else //volume and effects
|
||||
{
|
||||
if (charPos>=line.size())
|
||||
{
|
||||
invalidData=true;
|
||||
break;
|
||||
}
|
||||
note[0]=line[charPos++];
|
||||
if (charPos>=line.size())
|
||||
{
|
||||
invalidData=true;
|
||||
break;
|
||||
}
|
||||
note[1]=line[charPos++];
|
||||
if (charPos>=line.size())
|
||||
{
|
||||
invalidData=true;
|
||||
break;
|
||||
}
|
||||
note[2]=line[charPos++];
|
||||
note[3]=0;
|
||||
|
||||
logW("vol/eff \"%s\"", note);
|
||||
|
||||
if (iFine==2)
|
||||
{
|
||||
if (!opMaskPaste.vol)
|
||||
{
|
||||
iFine++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((iFine&1)==0)
|
||||
{
|
||||
if (!opMaskPaste.effectVal)
|
||||
{
|
||||
iFine++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
else if ((iFine&1)==1)
|
||||
{
|
||||
if (!opMaskPaste.effect)
|
||||
{
|
||||
iFine++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp(note,"...")==0 || strcmp(note," ")==0)
|
||||
{
|
||||
if (!(mode==GUI_PASTE_MODE_MIX_BG || mode==GUI_PASTE_MODE_MIX_FG ||
|
||||
mode==GUI_PASTE_MODE_INS_BG || mode==GUI_PASTE_MODE_INS_FG))
|
||||
{
|
||||
pat->data[j][iFine+1]=-1;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
unsigned int val=0;
|
||||
char symbol = '\0';
|
||||
|
||||
symbol = note[0];
|
||||
|
||||
if(iFine == 2)
|
||||
{
|
||||
sscanf(¬e[1],"%2d",&val);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
sscanf(¬e[1],"%2X",&val);
|
||||
}
|
||||
|
||||
logW("vol/eff symbol %c, value %02X", symbol, val);
|
||||
|
||||
if (!(mode==GUI_PASTE_MODE_MIX_BG || mode==GUI_PASTE_MODE_INS_BG) || pat->data[j][iFine+1]==-1)
|
||||
{
|
||||
//if (iFine<(3+e->curPat[iCoarse].effectCols*2)) pat->data[j][iFine+1]=val;
|
||||
if(iFine == 2) //volume
|
||||
{
|
||||
switch(symbol)
|
||||
{
|
||||
case 'v':
|
||||
{
|
||||
pat->data[j][iFine+1]=val;
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
else //effect
|
||||
{
|
||||
uint64_t eff = 0;
|
||||
|
||||
if(openmpt_format == 0)
|
||||
{
|
||||
eff = convert_effect_openmpt_mod(symbol, val); //up to 4 effects stored in one variable
|
||||
|
||||
if(((eff & 0x0f00) >> 8) == 0x0C) //set volume
|
||||
{
|
||||
pat->data[j][iFine]=eff & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
if(openmpt_format == 1)
|
||||
{
|
||||
eff = convert_effect_openmpt_s3m(symbol, val);
|
||||
}
|
||||
|
||||
if(openmpt_format == 2 || openmpt_format == 3) //set volume
|
||||
{
|
||||
eff = convert_effect_openmpt_xm(symbol, val);
|
||||
|
||||
if(((eff & 0x0f00) >> 8) == 0x0C)
|
||||
{
|
||||
pat->data[j][iFine]=eff & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
if(openmpt_format == 4 || openmpt_format == 5)
|
||||
{
|
||||
eff = convert_effect_openmpt_it(symbol, val);
|
||||
}
|
||||
|
||||
if(openmpt_format == 6)
|
||||
{
|
||||
eff = convert_effect_openmpt_mptm(symbol, val);
|
||||
}
|
||||
|
||||
pat->data[j][iFine+1]=((eff & 0xff00) >> 8);
|
||||
pat->data[j][iFine+2]=(eff & 0xff);
|
||||
|
||||
if(eff > 0xffff)
|
||||
{
|
||||
pat->data[j][iFine+3]=((eff & 0xff000000) >> 24);
|
||||
pat->data[j][iFine+4]=((eff & 0xff0000) >> 16);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
iFine++;
|
||||
|
||||
if(charPos >= line.size() - 1)
|
||||
{
|
||||
logW("line end");
|
||||
invalidData = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (invalidData)
|
||||
{
|
||||
logW("invalid OpenMPT clipboard data! failed at line %d char %d",i,charPos);
|
||||
logW("%s",line.c_str());
|
||||
break;
|
||||
}
|
||||
|
||||
j++;
|
||||
if (mode==GUI_PASTE_MODE_OVERFLOW && j>=e->curSubSong->patLen && curOrder<e->curSubSong->ordersLen-1)
|
||||
{
|
||||
j=0;
|
||||
curOrder++;
|
||||
}
|
||||
|
||||
if (mode==GUI_PASTE_MODE_FLOOD && i==data.size()-1)
|
||||
{
|
||||
i=1;
|
||||
}
|
||||
}
|
||||
|
||||
if (readClipboard) {
|
||||
if (settings.cursorPastePos) {
|
||||
cursor.y=j;
|
||||
if (cursor.y>=e->curSubSong->patLen) cursor.y=e->curSubSong->patLen-1;
|
||||
selStart=cursor;
|
||||
selEnd=cursor;
|
||||
updateScroll(cursor.y);
|
||||
}
|
||||
|
||||
makeUndo(GUI_UNDO_PATTERN_PASTE);
|
||||
}
|
||||
}
|
||||
|
||||
void FurnaceGUI::doPaste(PasteMode mode, int arg, bool readClipboard, String clipb) {
|
||||
if (readClipboard) {
|
||||
finishSelection();
|
||||
prepareUndo(GUI_UNDO_PATTERN_PASTE);
|
||||
char* clipText=SDL_GetClipboardText();
|
||||
if (clipText!=NULL) {
|
||||
if (clipText[0]) {
|
||||
clipboard=clipText;
|
||||
}
|
||||
SDL_free(clipText);
|
||||
}
|
||||
clipb=clipboard;
|
||||
}
|
||||
std::vector<String> data;
|
||||
String tempS;
|
||||
bool found_string = false;
|
||||
bool is_furnace = false;
|
||||
bool is_openmpt = false;
|
||||
int openmpt_format = 0;
|
||||
for (char i: clipb) {
|
||||
if (i=='\r') continue;
|
||||
if (i=='\n') {
|
||||
data.push_back(tempS);
|
||||
tempS="";
|
||||
continue;
|
||||
}
|
||||
tempS+=i;
|
||||
}
|
||||
data.push_back(tempS);
|
||||
|
||||
int startOff=-1;
|
||||
bool invalidData=false;
|
||||
if (data.size()<2) return;
|
||||
|
||||
if (data[0].find("org.tildearrow.furnace - Pattern Data")==0)
|
||||
{
|
||||
found_string = true;
|
||||
is_furnace = true;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
|
||||
while(text_format_headers[i] != NULL)
|
||||
{
|
||||
if (data[0].find(text_format_headers[i])==0)
|
||||
{
|
||||
found_string = true;
|
||||
is_openmpt = true;
|
||||
openmpt_format = i;
|
||||
break;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
if(!found_string) return;
|
||||
|
||||
if(is_furnace)
|
||||
{
|
||||
doPasteFurnace(mode, arg, readClipboard, clipb, data, startOff, invalidData);
|
||||
}
|
||||
|
||||
if(is_openmpt)
|
||||
{
|
||||
doPasteOpenMPT(mode, arg, readClipboard, clipb, data, openmpt_format);
|
||||
}
|
||||
}
|
||||
|
||||
void FurnaceGUI::doChangeIns(int ins) {
|
||||
finishSelection();
|
||||
prepareUndo(GUI_UNDO_PATTERN_CHANGE_INS);
|
||||
|
|
|
@ -2426,6 +2426,8 @@ class FurnaceGUI {
|
|||
void doInsert();
|
||||
void doTranspose(int amount, OperationMask& mask);
|
||||
String doCopy(bool cut, bool writeClipboard, const SelectionPoint& sStart, const SelectionPoint& sEnd);
|
||||
void doPasteFurnace(PasteMode mode, int arg, bool readClipboard, String clipb, std::vector<String> data, int startOff, bool invalidData);
|
||||
void doPasteOpenMPT(PasteMode mode, int arg, bool readClipboard, String clipb, std::vector<String> data, int openmpt_format);
|
||||
void doPaste(PasteMode mode=GUI_PASTE_MODE_NORMAL, int arg=0, bool readClipboard=true, String clipb="");
|
||||
void doChangeIns(int ins);
|
||||
void doInterpolate();
|
||||
|
|
Loading…
Reference in a new issue