void IScriptEditor::saveFile(QString filename) { file_t ft = files.value(filename); unsetBold(ft.item); if (! ft.modified) return; QFile file( setRelativePath(scriptFile,filename) ); if (! file.open(QIODevice::WriteOnly | QIODevice::Text)) { QMessageBox::question(this, tr("Unable to save file"), tr("Could not open file '%1' for writing.") .arg(filename)); return; } if (current == filename) { // Current file is open, use data from the editor instead, this one will // always have the most recent changes than the internal storage. ft.text->clear(); ft.text->append( editor.toPlainText() ); } file.write(*ft.text); file.close(); }
//-------------------------------- // //-------------------------------- bool AflMapData::saveMap(LPCSTR pFileName) { int i,j,k; FILE* pFile; pFile = fopen(pFileName,TEXT("wb")); if(!pFile) return false; m_strFileName = pFileName; setRelativePath(); fwrite(m_strMapHeader[MAP_BINHEADER],strlen(m_strMapHeader[MAP_BINHEADER])+1,1,pFile); //----------------------------- writeHeader(pFile,m_strMapHeader[MAP_VERSION],getVersion()); writeHeader(pFile,m_strMapHeader[MAP_MAPNAME],getMapName()); writeHeader(pFile,m_strMapHeader[MAP_BITMAP],getImageName(0)); writeHeader(pFile,m_strMapHeader[MAP_SPRITE],getImageName(1)); writeHeader(pFile,m_strMapHeader[MAP_WIDTH],getMapWidth()); writeHeader(pFile,m_strMapHeader[MAP_HEIGHT],getMapHeight()); writeHeader(pFile,m_strMapHeader[MAP_OPATTERN],getOutTipIndex()); writeHeader(pFile,m_strMapHeader[MAP_PARTSWIDTH],getTipWidth()); writeHeader(pFile,m_strMapHeader[MAP_PARTSHEIGHT],getTipHeight()); writeHeader(pFile,m_strMapHeader[MAP_OBJECT],getObjectFileName()); //----------------------------- //マップデータ for(k=0;k<4;k++) { if(!isZero(k)) { PSHORT pData = m_ptrData[k].get(); writeHeader(pFile,m_strMapHeader[MAP_MAPDATA0+k], pData,getMapWidth()*getMapHeight()*sizeof(short)); } } //----------------------------- //パーツ接触フラグ for(j=0;j<5;j++) { int nCollide; for(nCollide=i=0;i<0xffff/8;i++) if(m_byCollide[j][i]) nCollide = i+1; writeHeader(pFile,m_strMapHeader[MAP_PAERSCOLLIDE0+j],m_byCollide,nCollide); } //----------------------------- //----------------------------- //マップ個別フラグ writeHeader(pFile,m_strMapHeader[MAP_MAPFLAG0],getMapFlag(),getMapWidth()*getMapHeight()); //----------------------------- fclose(pFile); return true; }
e_scriptresult TScript::loadScript2(QString includeFile, QString parent) { QString fn = filename; if (includeFile.isEmpty()) { qDebug() << "Running loadScript() on" << filename; scriptstr.clear(); errorKeyword.clear(); curLine = 1; loadIntLine = 1; include.clear(); command.clear(); tevent.clear(); lineMap.clear(); QHashIterator<QString,TCustomScriptDialog*> i(dialogs); while (i.hasNext()) { i.next(); delete i.value(); } dialogs.clear(); } else { fn = setRelativePath(parent, includeFile); qDebug() << "Including" << fn; } qDebug() << "attempt:" << fn; if (QFile::exists(fn) == false) return se_FileNotExist; QFile f(fn); bool fo = f.open(QIODevice::ReadOnly | QIODevice::Text); if (fo == false) return se_FileCannotOpen; QString ba = f.readAll(); if (ba.length() < 1) return se_FileEmpty; // Remove comments, keep newlines: QString tmp; bool isCommented = false; QString lineFile = includeFile; if (lineFile.isEmpty()) lineFile = filename; int cLine = 1; for (int i = 0; i <= ba.length()-1; ++i) { QChar c = ba[i]; if (c == '\n') { // newline delWhitespace(&tmp); lineMap.insert(loadIntLine, QString("%1:%2") .arg(cLine) .arg(lineFile) ); if (tmp.length() > 0) { scriptstr.push_back(tmp + '\n'); loadIntLine++; } cLine++; isCommented = false; tmp.clear(); continue; } if (isCommented) // part of a comment, ignore. continue; if (c == ';') { // comment, skip anything after. isCommented = true; continue; } tmp.append(c); } if (tmp.length() > 0) // insert anything missing from very last line. scriptstr.push_back(tmp + '\n'); // This was an include, the first instance of loadScript() will take care of retreiving the rest. if (includeFile.length() > 0) return se_None; // Search script for functions and parse the meta. QString keyword; bool getKeyword = true; // Always begin with getting keyword. bool comment = false; enum { // Expecting ex_Unknown = 0, // If we use this we must pose an error too. ex_Block, ex_Brace, ex_Statement, ex_Ignore, // ignore until next block (still handles nesting levels) ex_Include = 5, ex_Command, ex_Event, ex_Timer, ex_ScriptName, ex_FunctionName = 10, ex_MenuType, ex_MenuTitle, ex_MenuFunction, ex_DialogName, ex_DialogTitle = 15, ex_DialogGeometry, ex_DialogEmbed, ex_DialogIcon, ex_DialogLabel, ex_DialogButton = 20, ex_DialogEditBox, ex_DialogTextBox, ex_DialogListBox, ex_DialogPaint, ex_DialogText = 25 }; enum { st_None = 0, // used when waiting for block name keyword st_Meta, st_Function, st_Menu, st_Dialog }; int state = st_None; int ex = ex_Block; // We expect to find a script block to begin with. either function, script or menu. int n = 0; // Nesting level. 0 is where script blocks are at (script, function, menu, etc.) QString temp[3]; TCustomScriptDialog *dialog = NULL; // Reset the custom menues, they'll be set up later on in here... resetMenu(customNicklistMenu); resetMenu(customChannelMenu); resetMenu(customQueryMenu); resetMenu(customStatusMenu); fnindex.clear(); // re-load function index for (int i = 0; i <= scriptstr.length()-1; ++i) { QChar cc = scriptstr[i]; errorKeyword = keyword + cc; if (cc == '\n') curLine++; if (ex != ex_Ignore) { if (cc == '\\') { // Escape, skip completely and add to keyword if ((i == scriptstr.length()-1) || (scriptstr[i+1] == '\n')) return se_EscapeOnEndLine; keyword += scriptstr[i+1]; i++; continue; } /* Comment handling */ /* Put ; anywhere but must end with newline. */ if (cc == '\n') comment = false; if (comment) continue; if (cc == ';') { comment = true; continue; } /* **************** */ } if (cc == '{') { if ((ex != ex_Brace) && (ex != ex_Ignore) && (n == 0)) return se_UnexpectedToken; n++; } if (cc == '}') { if (n == 0) return se_UnexpectedToken; n--; if (state == st_Dialog) { dialogs.insert( dialog->getName(), dialog ); connect(dialog, SIGNAL(runEvent(e_iircevent,QStringList)), this, SLOT(runEvent(e_iircevent,QStringList))); state = st_None; } if (n == 0) ex = ex_Block; } if (ex == ex_Brace) { if ((cc != ' ') && (cc != '\t') && (cc != '\n') && (cc != '{') && (cc != '}')) return se_UnexpectedToken; if ((cc == ' ') || (cc == '\t') || (cc == '\n')) continue; ex = ex_Statement; continue; } if (cc == '}') continue; if (ex == ex_FunctionName) { // Stop this one at ( // If we encounter \n first, pose error. if (cc == '\n') return se_UnexpectedNewline; if (i == scriptstr.length()-1) return se_UnexpectedFinish; if (cc == '(') { fnindex.insert(keyword.toUpper(), i); ex = ex_Ignore; continue; } if (cc == ' ') { QChar cc2 = scriptstr[i+1]; if (cc2 == '(') continue; else return se_UnexpectedToken; } } // Newline, receiving keyword but keyword got is none. ignore. if ((cc == '\n') && (getKeyword == true) && (keyword.length() == 0)) continue; // Newline, space receiving keyword and got a keyword. parse. if (((cc == '\n') || (cc == ' ')) && (getKeyword == true) && (keyword.length() >= 0)) { QString keywup = keyword.toUpper(); if (n == 0) { // Here we always expect script blocks. if (ex == ex_Block) { if (keywup == "SCRIPT") { ex = ex_ScriptName; state = st_Meta; keyword.clear(); continue; } else if (keywup == "META") { ex = ex_Brace; state = st_Meta; keyword.clear(); continue; } else if (keywup == "FUNCTION") { ex = ex_FunctionName; state = st_Function; keyword.clear(); continue; } else if (keywup == "MENU") { ex = ex_MenuType; state = st_Menu; keyword.clear(); continue; } else if (keywup == "DIALOG") { ex = ex_DialogName; state = st_Dialog; keyword.clear(); continue; } else return se_InvalidBlockType; } if (ex == ex_ScriptName) { name = keyword; ex = ex_Brace; keyword.clear(); continue; } if (ex == ex_DialogName) { dialog = new TCustomScriptDialog(this, keyword, dlgParent); ex = ex_Brace; keyword.clear(); continue; } if (ex == ex_MenuType) { temp[0] = keyword.toUpper(); state = st_Menu; ex = ex_Brace; continue; } } if (n > 0) { if (state == st_Meta) { if (ex == ex_Statement) { keyword.clear(); // this is safe here. if (keywup == "INCLUDE") { ex = ex_Include; continue; } else if (keywup == "COMMAND") { ex = ex_Command; continue; } else if (keywup == "EVENT") { ex = ex_Event; continue; } else if (keywup == "TIMER") { ex = ex_Timer; continue; } else return se_InvalidMetaCommand; } if (ex == ex_Include) { if (cc == ' ') { keyword += cc; continue; } include.push_back(keyword); e_scriptresult r = loadScript2(keyword, fn); keyword.clear(); ex = ex_Statement; if (r != se_None) return r; continue; } if ((ex == ex_Command) || (ex == ex_Event) || (ex == ex_Timer)) { if (temp[0].length() == 0) temp[0] = keyword; // command name else temp[1] = keyword; // function keyword.clear(); if (((temp[0].length() == 0) || (temp[1].length() == 0)) && (cc == '\n')) return se_UnexpectedNewline; if (cc == '\n') { // this one will run if both temp are filled. if (ex == ex_Command) command.insert(temp[0].toUpper(), temp[1]); if (ex == ex_Event) { e_iircevent evt = getEvent(temp[0]); if (evt == te_noevent) return se_InvalidEvent; tevent.insertMulti(evt, temp[1]); } if (ex == ex_Timer) { if (timers.contains(temp[0].toUpper()) == true) goto loadScript__ex_TimerAdd_Cleanup; TTimer *tmr = new TTimer(temp[1].toUpper(), this); connect(tmr, SIGNAL(timeout(QString)), this, SLOT(timerTimeout(QString))); timers.insert(temp[0].toUpper(), tmr); } loadScript__ex_TimerAdd_Cleanup: ex = ex_Statement; temp[0].clear(); temp[1].clear(); keyword.clear(); continue; } keyword.clear(); continue; } } if (state == st_Dialog) { if (ex == ex_Statement) { keyword.clear(); if (keywup == "TITLE") ex = ex_DialogTitle; else if (keywup == "GEOMETRY") ex = ex_DialogGeometry; else if (keywup == "EMBED") { // embed c|l|p|s // channel, listbox, pm, status ex = ex_DialogEmbed; } else if (keywup == "PAINT") { // paint @wname x y w h } else if (keywup == "TEXT") { // text @name x y w h } else if (keywup == "LABEL") ex = ex_DialogLabel; else if (keywup == "BUTTON") ex = ex_DialogButton; else if (keywup == "EDITBOX") ex = ex_DialogEditBox; else if (keywup == "TEXTBOX") ex = ex_DialogTextBox; else if (keywup == "LISTBOX") ex = ex_DialogListBox; else return se_UnexpectedToken; continue; } if (ex == ex_DialogTitle) { for (; i <= scriptstr.length()-1; i++) { QChar c = scriptstr[i]; if (c == '\n') break; keyword += c; } dialog->setTitle(keyword); keyword.clear(); ex = ex_Statement; continue; } if (ex == ex_DialogGeometry) { int param = 2; // 1X 2Y 3W 4H int X, Y, W, H; X = keyword.toInt(); keyword.clear(); for (i++; i <= scriptstr.length()-1; i++) { QChar c = scriptstr[i]; if ((c == ' ') || (c == '\n')) { if (param == 2) Y = keyword.toInt(); if (param == 3) W = keyword.toInt(); if (param == 4) H = keyword.toInt(); keyword.clear(); param++; } if (c == '\n') break; if (param == 5) break; keyword += c; } if (param != 5) return se_InvalidParamCount; dialog->setGeometry(X, Y, W, H); keyword.clear(); ex = ex_Statement; continue; } if (ex == ex_DialogEmbed) { } if (ex >= ex_DialogLabel) { int param = 2; int X, Y, W, H = 0; QString oname = keyword; QString arg; keyword.clear(); for (i++; i <= scriptstr.length()-1; i++) { QChar c = scriptstr[i]; if (param < 6) { if ((c == ' ') || (c == '\n')) { if (param == 2) X = keyword.toInt(); if (param == 3) Y = keyword.toInt(); if (param == 4) W = keyword.toInt(); if (param == 5) H = keyword.toInt(); keyword.clear(); param++; } } if (c == '\n') break; if (param >= 6) arg += c; else keyword += c; } if (param != 6) return se_InvalidParamCount; arg = arg.mid(1); if (ex == ex_DialogLabel) dialog->addLabel(oname, X, Y, W, H, arg); if (ex == ex_DialogButton) dialog->addButton(oname, X, Y, W, H, arg); if (ex == ex_DialogEditBox) dialog->addEditbox(oname, X, Y, W, H); if (ex == ex_DialogTextBox) dialog->addTextbox(oname, X, Y, W, H); if (ex == ex_DialogListBox) dialog->addListbox(oname, X, Y, W, H); keyword.clear(); ex = ex_Statement; continue; } } if (state == st_Menu) { if (ex == ex_Statement) { if (temp[0] == "NICKLIST") createMenu(i, 'n'); if (temp[0] == "CHANNEL") createMenu(i, 'c'); if (temp[0] == "QUERY") createMenu(i, 'q'); if (temp[0] == "STATUS") createMenu(i, 's'); --i; temp[0].clear(); state = st_None; ex = ex_Brace; } } } keyword.clear(); continue; } keyword += cc; } if (n > 0) return se_UnexpectedFinish; qDebug() << "Script" << name << "(re)loaded with:"; qDebug() << " -" << fnindex.count() << "functions."; qDebug() << " -" << tevent.count() << "events."; qDebug() << " -" << include.count() << "includes."; qDebug() << " -" << command.count() << "commands."; qDebug() << " -" << timers.count() << "timers."; qDebug() << " -" << dialogs.count() << "dialogs."; qDebug() << "---"; return se_None; }
void IScriptEditor::setupTreeView(QStandardItem *parent) { QFile file(setRelativePath(scriptFile, parent->text())); QByteArray data; QTextCursor cursor = editor.textCursor(); cursor.movePosition(QTextCursor::Start); int def = cursor.position(); QPoint scroll = editor.verticalScrollBar()->pos(); if (! file.open(QIODevice::ReadOnly | QIODevice::Text)) { int q = QMessageBox::question(this, tr("Unable to open file"), tr("Unable to open '%1'\r\nAttempt to create it?") .arg(parent->text()), QMessageBox::Yes | QMessageBox::No); if (q == QMessageBox::Yes) { if (! file.open(QIODevice::WriteOnly | QIODevice::Text)) { QMessageBox::question(this, tr("Unable to create file"), tr("Unable to create file '%1'") .arg(parent->text())); file_t ft; ft.modified = false; ft.item = parent; ft.text = new QByteArray(); ft.textCursor = def; ft.scrollPos = scroll; files.insert(parent->text(), ft); return; } else if (files.contains(parent->text())) { file.write( *files.value(parent->text()).text ); file.close(); } } file_t ft; ft.modified = false; ft.item = parent; ft.textCursor = def; ft.scrollPos = scroll; if (files.contains(parent->text())) { file_t f = files.value(parent->text()); ft.text = f.text; ft.textCursor = f.textCursor; ft.scrollPos = f.scrollPos; } else ft.text = new QByteArray(); files.insert(parent->text(), ft); } else { data = file.readAll(); file.close(); file_t ft; ft.modified = false; ft.item = parent; ft.text = new QByteArray(data); ft.textCursor = def; ft.scrollPos = scroll; if (files.contains(current)) { file_t f = files.value(current); ft.textCursor = f.textCursor; ft.scrollPos = f.scrollPos; } files.insert(parent->text(), ft); } enum { st_find=0, st_meta, st_include }; /* States: * * Find: Finding the meta block * * Meta: We found meta, now find include keywords until next }. * * Include: Reading the include path until newline */ bool comment = false; // If this is set to true, everything is ignored until newline int state = st_find; QString keyword; for (int i = 0; i <= data.length()-1; i++) { QChar c(data[i]); if (c == ';') comment = true; if ((comment) && (c == '\n')) { comment = false; keyword.clear(); // Make sure it's empty for next line. continue; } if (comment) continue; if (state == st_find) { if (((c == ' ') || c == '\n') && (! keyword.isEmpty())) { if ((keyword.toUpper() == "SCRIPT") || (keyword.toUpper() == "META")) { // This should be the first keyword the script contains. // skip until the { for (; i <= data.length()-1; i++) { if (data[i] == '{') { keyword.clear(); state = st_meta; break; } } } else return; // No meta in this script. } else if ((c == '\n') && (keyword.isEmpty())) continue; else keyword += c; continue; } if (state == st_meta) { if (c == ' ') { if (keyword.isEmpty()) continue; if (keyword.toUpper() == "INCLUDE") { // Found include file... state = st_include; keyword.clear(); continue; } else keyword.clear(); } else if (c == '}') return; else if (c == '\n') continue; else keyword += c; } if (state == st_include) { if (c == '\n') { if (keyword.isEmpty()) // empty include set, just ignore this. state = st_meta; else { QStandardItem *item = new QStandardItem(keyword); parent->appendRow(item); setupTreeView(item); keyword.clear(); state = st_meta; } } else keyword += c; } } }