/*--------------------------------------------------------------------------*/ char *TerminalGetString(char *prompt) { if (InitTerm) { InitializeTerminal(); InitTerm = FALSE; } newLine(); setCurrentPrompt(prompt); /* print the prompt */ displayPrompt(); /* initialize history search */ setSearchedTokenInScilabHistory(NULL); for (;;) { unsigned char cur_char = TerminalGetchar(); if (cur_char <= 0) { return NULL; } /* http://bugzilla.scilab.org/show_bug.cgi?id=1052 */ if (ismenu () == 1) { /* Abort current line */ return NULL; } if ( (cur_char == CR_1) || (cur_char == CR_2) ) { if ( isHistorySearch() ) { putLineSearchedHistory(); } else { char *line = getCurrentLine(); TerminalPutc('\n'); appendLineToScilabHistory(line); return line; } } else { TerminalPutc(cur_char); addCharacterCurrentLine(cur_char); } } return NULL; }
U32 Tokenizer::getTokenLineOffset() { U32 lineNumber = getCurrentLine(); if (lineNumber >= mLinePositions.size()) return 0; U32 linePosition = mLinePositions[lineNumber]; if (linePosition >= mStartPos) return 0; return mStartPos - linePosition; }
/*--------------------------------------------------------------------------*/ void redrawLine(void) { int i =0; char *line = getCurrentLine(); displayPrompt(); for (i = max_pos; i > cur_pos; i--) backSpace (); if (line) { copyLine(line); FREE(line); line = NULL; } }
void KNNntpClient::doPostArticle() { KNLocalArticle *art = static_cast<KNLocalArticle *>(job->data()); sendSignal(TSsendArticle); if(art->messageID(false) != 0) { int rep; if(!sendCommand(QCString("STAT ") + art->messageID(false)->as7BitString(false), rep)) return; if(rep == 223) // 223 n <a> article retrieved - request text separately { #ifndef NDEBUG qDebug("knode: STAT successful, we have probably already sent this article."); #endif return; // the article is already on the server, lets put it silently into the send folder } } if(!sendCommandWCheck("POST", 340)) // 340 send article to be posted. End with <CR-LF>.<CR-LF> return; if(art->messageID(false) == 0) // article has no message ID => search for a ID in the response { QCString s = getCurrentLine(); int start = s.findRev(QRegExp("<[^\\s]*@[^\\s]*>")); if(start != -1) // post response includes a recommended id { int end = s.find('>', start); art->messageID()->from7BitString(s.mid(start, end - start + 1)); art->assemble(); #ifndef NDEBUG qDebug("knode: using the message-id recommended by the server: %s", s.mid(start, end - start + 1).data()); #endif } } if(!sendMsg(art->encodedContent(true))) return; if(!checkNextResponse(240)) // 240 article posted ok return; }
bool Tokenizer::regressToken(const bool crossLine) { if (mTokenIsCurrent == true) { AssertFatal(mCurrTokenBuffer[0] != '\0', "No token, but marked as current?"); mTokenIsCurrent = false; return true; } U32 currPosition = 0; mCurrTokenBuffer[0] = '\0'; mTokenIsQuoted = false; // Store the beginning of the previous advance // and the beginning of the current advance mCurrPos = mStartPos; // Back up to the first character of the previous token mStartPos--; while (mStartPos > 0) { char c = mpBuffer[mStartPos]; bool cont = true; if (mSingleTokens && dStrchr(mSingleTokens, c)) { if (currPosition == 0) { mCurrTokenBuffer[currPosition++] = c; mStartPos--; cont = false; break; } else { // End of token cont = false; } } else { switch (c) { case ' ': case '\t': if (currPosition == 0) { // Token hasn't started yet... mStartPos--; } else { // End of token mStartPos--; cont = false; } break; case '\r': case '\n': if (crossLine == true && currPosition == 0) { // Windows line ending if (mStartPos > 0 && mpBuffer[mStartPos] == '\r' && mpBuffer[mStartPos - 1] == '\n') mStartPos -= 2; // Not sure if this ever happens but just in case else if (mStartPos > 0 && mpBuffer[mStartPos] == '\n' && mpBuffer[mStartPos - 1] == '\r') mStartPos -= 2; // Unix line endings should only have a single line break character else mStartPos--; } else { cont = false; break; } break; default: if (c == '\"' || c == '\'') { // Quoted token U32 endLine = getCurrentLine(); mStartPos--; while (mpBuffer[mStartPos] != c) { AssertISV(mStartPos < 0, avar("Beginning of file reached before finding begin quote. Quote ended: (%s: %d)", getFileName(), endLine)); mCurrTokenBuffer[currPosition++] = mpBuffer[mStartPos--]; } mTokenIsQuoted = true; mStartPos--; cont = false; } else if (c == '/' && mStartPos > 0 && mpBuffer[mStartPos - 1] == '/') { // Line quote... // Clear out anything saved already currPosition = 0; mStartPos -= 2; } else { mCurrTokenBuffer[currPosition++] = c; mStartPos--; } break; } } if (cont == false) break; } mCurrTokenBuffer[currPosition] = '\0'; // Reveres the token for (U32 i = 0; i < currPosition / 2; i++) { char c = mCurrTokenBuffer[i]; mCurrTokenBuffer[i] = mCurrTokenBuffer[currPosition - i - 1]; mCurrTokenBuffer[currPosition - i - 1] = c; } mStartPos++; if (mStartPos == mCurrPos) return false; return true; }
bool Tokenizer::advanceToken(const bool crossLine, const bool assertAvail) { if (mTokenIsCurrent == true) { AssertFatal(mCurrTokenBuffer[0] != '\0', "No token, but marked as current?"); mTokenIsCurrent = false; return true; } U32 currPosition = 0; mCurrTokenBuffer[0] = '\0'; mTokenIsQuoted = false; // Store the beginning of the previous advance // and the beginning of the current advance mStartPos = mCurrPos; while (mCurrPos < mBufferSize) { char c = mpBuffer[mCurrPos]; bool cont = true; if (mSingleTokens && dStrchr(mSingleTokens, c)) { if (currPosition == 0) { mCurrTokenBuffer[currPosition++] = c; mCurrPos++; cont = false; break; } else { // End of token cont = false; } } else { switch (c) { case ' ': case '\t': if (currPosition == 0) { // Token hasn't started yet... mCurrPos++; } else { // End of token mCurrPos++; cont = false; } break; case '\r': case '\n': if (crossLine == true) { // Windows line ending if (mpBuffer[mCurrPos] == '\r' && mpBuffer[mCurrPos + 1] == '\n') mCurrPos += 2; // Not sure if this ever happens but just in case else if (mpBuffer[mCurrPos] == '\n' && mpBuffer[mCurrPos + 1] == '\r') mCurrPos += 2; // Unix line endings should only have a single line break character else mCurrPos++; } else { cont = false; break; } break; default: if (c == '\"' || c == '\'') { // Quoted token U32 startLine = getCurrentLine(); mCurrPos++; // Store the beginning of the token mStartPos = mCurrPos; while (mpBuffer[mCurrPos] != c) { AssertISV(mCurrPos < mBufferSize, avar("End of file before quote closed. Quote started: (%s: %d)", getFileName(), startLine)); AssertISV((mpBuffer[mCurrPos] != '\n' && mpBuffer[mCurrPos] != '\r'), avar("End of line reached before end of quote. Quote started: (%s: %d)", getFileName(), startLine)); mCurrTokenBuffer[currPosition++] = mpBuffer[mCurrPos++]; } mTokenIsQuoted = true; mCurrPos++; cont = false; } else if (c == '/' && mpBuffer[mCurrPos+1] == '/') { // Line quote... if (currPosition == 0) { // continue to end of line, then let crossLine determine on the next pass while (mCurrPos < mBufferSize && (mpBuffer[mCurrPos] != '\n' && mpBuffer[mCurrPos] != '\r')) mCurrPos++; } else { // This is the end of the token. Continue to EOL while (mCurrPos < mBufferSize && (mpBuffer[mCurrPos] != '\n' && mpBuffer[mCurrPos] != '\r')) mCurrPos++; cont = false; } } else if (c == '/' && mpBuffer[mCurrPos+1] == '*') { // Block quote... if (currPosition == 0) { // continue to end of block, then let crossLine determine on the next pass while (mCurrPos < mBufferSize - 1 && (mpBuffer[mCurrPos] != '*' || mpBuffer[mCurrPos + 1] != '/')) mCurrPos++; if (mCurrPos < mBufferSize - 1) mCurrPos += 2; } else { // This is the end of the token. Continue to EOL while (mCurrPos < mBufferSize - 1 && (mpBuffer[mCurrPos] != '*' || mpBuffer[mCurrPos + 1] != '/')) mCurrPos++; if (mCurrPos < mBufferSize - 1) mCurrPos += 2; cont = false; } } else { // If this is the first non-token character then store the // beginning of the token if (currPosition == 0) mStartPos = mCurrPos; mCurrTokenBuffer[currPosition++] = c; mCurrPos++; } break; } } if (cont == false) break; } mCurrTokenBuffer[currPosition] = '\0'; if (assertAvail == true) AssertISV(currPosition != 0, avar("Error parsing: %s at or around line: %d", getFileName(), getCurrentLine())); if (mCurrPos == mBufferSize) return false; return true; }
void KNNntpClient::doFetchGroups() { KNGroupListData *target = static_cast<KNGroupListData *>(job->data()); sendSignal(TSdownloadGrouplist); errorPrefix = i18n("The group list could not be retrieved.\nThe following error occurred:\n"); progressValue = 100; predictedLines = 30000; // rule of thumb ;-) if(!sendCommandWCheck("LIST", 215)) // 215 list of newsgroups follows return; char *s, *line; QString name; KNGroup::Status status; bool subscribed; while(getNextLine()) { line = getCurrentLine(); if(line[0] == '.') { if(line[1] == '.') line++; // collapse double period into one else if(line[1] == 0) break; // message complete } s = strchr(line, ' '); if(!s) { #ifndef NDEBUG qDebug("knode: retrieved broken group-line - ignoring"); #endif } else { s[0] = 0; // cut string name = QString::fromUtf8(line); if(target->subscribed.contains(name)) { target->subscribed.remove(name); // group names are unique, we wont find it again anyway... subscribed = true; } else subscribed = false; while(s[1] != 0) s++; // the last character determines the moderation status switch(s[0]) { case 'n' : status = KNGroup::readOnly; break; case 'y' : status = KNGroup::postingAllowed; break; case 'm' : status = KNGroup::moderated; break; default : status = KNGroup::unknown; } target->groups->append(new KNGroupInfo(name, QString::null, false, subscribed, status)); } doneLines++; } if(!job->success() || job->canceled()) return; // stopped... QSortedVector<KNGroupInfo> tempVector; target->groups->toVector(&tempVector); tempVector.sort(); if(target->getDescriptions) { errorPrefix = i18n("The group descriptions could not be retrieved.\nThe following error occurred:\n"); progressValue = 100; doneLines = 0; predictedLines = target->groups->count(); sendSignal(TSdownloadDesc); sendSignal(TSprogressUpdate); int rep; if(!sendCommand("LIST NEWSGROUPS", rep)) return; if(rep == 215) // 215 informations follows { QString description; KNGroupInfo info; int pos; while(getNextLine()) { line = getCurrentLine(); if(line[0] == '.') { if(line[1] == '.') line++; // collapse double period into one else if(line[1] == 0) break; // message complete } s = line; while(*s != '\0' && *s != '\t' && *s != ' ') s++; if(*s == '\0') { #ifndef NDEBUG qDebug("knode: retrieved broken group-description - ignoring"); #endif } else { s[0] = 0; // terminate groupname s++; while(*s == ' ' || *s == '\t') s++; // go on to the description name = QString::fromUtf8(line); if(target->codecForDescriptions) // some countries use local 8 bit characters in the tag line description = target->codecForDescriptions->toUnicode(s); else description = QString::fromLocal8Bit(s); info.name = name; if((pos = tempVector.bsearch(&info)) != -1) tempVector[pos]->description = description; } doneLines++; } } if(!job->success() || job->canceled()) return; // stopped... } target->groups->setAutoDelete(false); tempVector.toList(target->groups); target->groups->setAutoDelete(true); sendSignal(TSwriteGrouplist); if(!target->writeOut()) job->setErrorString(i18n("Unable to write the group list file")); }
// authentication on demand bool KNNntpClient::sendCommand(const QCString &cmd, int &rep) { if(!KNProtocolClient::sendCommand(cmd, rep)) return false; if(rep == 480) // 480 requesting authorization { //qDebug("knode: Authorization requested"); if(!account.user().length()) { job->setErrorString(i18n("Authentication failed.\nCheck your username and password.")); job->setAuthError(true); closeConnection(); return false; } //qDebug("knode: user: %s",account.user().data()); QCString command = "AUTHINFO USER "; command += account.user().local8Bit(); if(!KNProtocolClient::sendCommand(command, rep)) return false; if(rep == 381) // 381 PASS required { //qDebug("knode: Password required"); if(!account.pass().length()) { job->setErrorString(i18n("Authentication failed.\nCheck your username and password.\n\n%1").arg(getCurrentLine())); job->setAuthError(true); closeConnection(); return false; } //qDebug("knode: pass: %s",account.pass().data()); command = "AUTHINFO PASS "; command += account.pass().local8Bit(); if(!KNProtocolClient::sendCommand(command, rep)) return false; } if(rep == 281) // 281 authorization success { #ifndef NDEBUG qDebug("knode: Authorization successful"); #endif if(!KNProtocolClient::sendCommand(cmd, rep)) // retry the original command return false; } else { job->setErrorString(i18n("Authentication failed.\nCheck your username and password.\n\n%1").arg(getCurrentLine())); job->setAuthError(true); closeConnection(); return false; } } return true; }
bool KNNntpClient::openConnection() { currentGroup = QString::null; QString oldPrefix = errorPrefix; errorPrefix = i18n("Unable to connect.\nThe following error occurred:\n"); if(!KNProtocolClient::openConnection()) return false; progressValue = 30; int rep; if(!getNextResponse(rep)) return false; if((rep < 200) || (rep > 299)) // RFC977: 2xx - Command ok { handleErrors(); return false; } progressValue = 50; if(!sendCommand("MODE READER", rep)) return false; if(rep == 500) { #ifndef NDEBUG qDebug("knode: \"MODE READER\" command not recognized."); #endif } else if((rep < 200) || (rep > 299)) // RFC977: 2xx - Command ok { handleErrors(); return false; } progressValue = 60; // logon now, some newsserver send a incomplete group list otherwise if(account.needsLogon() && !account.user().isEmpty()) { //qDebug("knode: user: %s",account.user().latin1()); QCString command = "AUTHINFO USER "; command += account.user().local8Bit(); if(!KNProtocolClient::sendCommand(command, rep)) return false; if(rep == 381) // 381 PASS required { //qDebug("knode: Password required"); if(!account.pass().length()) { job->setErrorString(i18n("Authentication failed.\nCheck your username and password.")); job->setAuthError(true); return false; } //qDebug("knode: pass: %s",account.pass().latin1()); command = "AUTHINFO PASS "; command += account.pass().local8Bit(); if(!KNProtocolClient::sendCommand(command, rep)) return false; if(rep == 281) // 281 authorization success { #ifndef NDEBUG qDebug("knode: Authorization successful"); #endif } else { #ifndef NDEBUG qDebug("knode: Authorization failed"); #endif job->setErrorString(i18n("Authentication failed.\nCheck your username and password.\n\n%1").arg(getCurrentLine())); job->setAuthError(true); closeConnection(); return false; } } else { if(rep == 281) // 281 authorization success { #ifndef NDEBUG qDebug("knode: Authorization successful"); #endif } else { if((rep == 482) || (rep == 500)) //482 Authentication rejected { #ifndef NDEBUG qDebug("knode: Authorization failed"); // we don't care, the server can refuse the info #endif } else { handleErrors(); return false; } } } } progressValue = 70; errorPrefix = oldPrefix; return true; }
void KNNntpClient::doFetchNewHeaders() { KNGroup *target = static_cast<KNGroup *>(job->data()); char *s; int first = 0, last = 0, oldlast = 0, toFetch = 0, rep = 0; QCString cmd; target->setLastFetchCount(0); sendSignal(TSdownloadNew); errorPrefix = i18n("No new articles could be retrieved for\n%1/%2.\nThe following error occurred:\n") .arg(account.server()).arg(target->groupname()); cmd = "GROUP "; cmd += target->groupname().utf8(); if(!sendCommandWCheck(cmd, 211)) // 211 n f l s group selected { return; } currentGroup = target->groupname(); progressValue = 90; s = strchr(getCurrentLine(), ' '); if(s) { s++; s = strchr(s, ' '); } if(s) { s++; first = atoi(s); target->setFirstNr(first); s = strchr(s, ' '); } if(s) { last = atoi(s); } else { QString tmp = i18n("No new articles could be retrieved.\nThe server sent a malformatted response:\n"); tmp += getCurrentLine(); job->setErrorString(tmp); closeConnection(); return; } if(target->lastNr() == 0) //first fetch { if(first > 0) oldlast = first - 1; else oldlast = first; } else oldlast = target->lastNr(); toFetch = last - oldlast; //qDebug("knode: last %d oldlast %d toFetch %d\n",last,oldlast,toFetch); if(toFetch <= 0) { //qDebug("knode: No new Articles in group\n"); target->setLastNr(last); // don't get stuck when the article numbers wrap return; } if(toFetch > target->maxFetch()) { toFetch = target->maxFetch(); //qDebug("knode: Fetching only %d articles\n",toFetch); } progressValue = 100; predictedLines = toFetch; // get list of additional headers provided by the XOVER command // see RFC 2980 section 2.1.7 QStrList headerformat; cmd = "LIST OVERVIEW.FMT"; if(sendCommand(cmd, rep) && rep == 215) { QStrList tmp; if(getMsg(tmp)) { for(QCString s = tmp.first(); s; s = tmp.next()) { s = s.stripWhiteSpace(); // remove the mandatory xover header if(s == "Subject:" || s == "From:" || s == "Date:" || s == "Message-ID:" || s == "References:" || s == "Bytes:" || s == "Lines:") continue; else headerformat.append(s); } } } //qDebug("knode: KNNntpClient::doFetchNewHeaders() : xover %d-%d", last-toFetch+1, last); cmd.sprintf("xover %d-%d", last - toFetch + 1, last); if(!sendCommand(cmd, rep)) return; // no articles in selected range... if(rep == 420) // 420 No article(s) selected { target->setLastNr(last); return; } else if(rep != 224) // 224 success { handleErrors(); return; } QStrList headers; if(!getMsg(headers)) { return; } progressValue = 1000; sendSignal(TSprogressUpdate); sendSignal(TSsortNew); mutex.lock(); target->insortNewHeaders(&headers, &headerformat, this); target->setLastNr(last); mutex.unlock(); }
void KNNntpClient::doCheckNewGroups() { KNGroupListData *target = static_cast<KNGroupListData *>(job->data()); sendSignal(TSdownloadNewGroups); errorPrefix = i18n("New groups could not be retrieved.\nThe following error occurred:\n"); progressValue = 100; predictedLines = 30; // rule of thumb ;-) QCString cmd; cmd.sprintf("NEWGROUPS %.2d%.2d%.2d 000000", target->fetchSince.year() % 100, target->fetchSince.month(), target->fetchSince.day()); if(!sendCommandWCheck(cmd, 231)) // 231 list of new newsgroups follows return; char *s, *line; QString name; KNGroup::Status status; QSortedList<KNGroupInfo> tmpList; tmpList.setAutoDelete(true); while(getNextLine()) { line = getCurrentLine(); if(line[0] == '.') { if(line[1] == '.') line++; // collapse double period into one else if(line[1] == 0) break; // message complete } s = strchr(line, ' '); if(!s) { #ifndef NDEBUG qDebug("knode: retrieved broken group-line - ignoring"); #endif } else { s[0] = 0; // cut string name = QString::fromUtf8(line); while(s[1] != 0) s++; // the last character determines the moderation status switch(s[0]) { case 'n' : status = KNGroup::readOnly; break; case 'y' : status = KNGroup::postingAllowed; break; case 'm' : status = KNGroup::moderated; break; default : status = KNGroup::unknown; } tmpList.append(new KNGroupInfo(name, QString::null, true, false, status)); } doneLines++; } if(!job->success() || job->canceled()) return; // stopped... if(target->getDescriptions) { errorPrefix = i18n("The group descriptions could not be retrieved.\nThe following error occurred:\n"); progressValue = 100; doneLines = 0; predictedLines = tmpList.count() * 3; sendSignal(TSdownloadDesc); sendSignal(TSprogressUpdate); cmd = "LIST NEWSGROUPS "; QStrList desList; char *s; int rep; for(KNGroupInfo *group = tmpList.first(); group; group = tmpList.next()) { if(!sendCommand(cmd + group->name.utf8(), rep)) return; if(rep != 215) // 215 informations follows break; desList.clear(); if(!getMsg(desList)) return; if(desList.count() > 0) // group has a description { s = desList.first(); while(*s != - '\0' && *s != '\t' && *s != ' ') s++; if(*s == '\0') { #ifndef NDEBUG qDebug("knode: retrieved broken group-description - ignoring"); #endif } else { while(*s == ' ' || *s == '\t') s++; // go on to the description if(target->codecForDescriptions) // some countries use local 8 bit characters in the tag line group->description = target->codecForDescriptions->toUnicode(s); else group->description = QString::fromLocal8Bit(s); } } } } sendSignal(TSloadGrouplist); if(!target->readIn()) { job->setErrorString(i18n("Unable to read the group list file")); return; } target->merge(&tmpList); sendSignal(TSwriteGrouplist); if(!target->writeOut()) { job->setErrorString(i18n("Unable to write the group list file")); return; } }
int pushHistory (void) { his.lineno = getCurrentLine(); getCurrentFile(his.filename, sizeof(his.filename)); return add_history(&his); }
//============================================================================= // METHOD : SPELLcodeTreeNode::eventCall() //============================================================================= void SPELLcodeTreeNode::eventCall( const std::string& codeId, unsigned int lineNo ) { SPELLcodeTreeLineIF* currentLine = getCurrentLine(); SPELLcodeTreeNodeIF* node = new SPELLcodeTreeNode(m_depth+1, codeId, lineNo, currentLine); currentLine->addChildCode(node); }
void CodeView::reload() { int currentLine = getCurrentLine(); readSourceFile(m_sourceFile); setLine(currentLine); }
void jumpToNextChange(bool down, bool wrapAround) { HWND view = getCurrentView(); const int sci_search_mask = (1 << MARKER_MOVED_LINE) | (1 << MARKER_CHANGED_LINE) | (1 << MARKER_ADDED_LINE) | (1 << MARKER_REMOVED_LINE) | (1 << MARKER_BLANK_LINE); const int sci_marker_direction = down ? SCI_MARKERNEXT : SCI_MARKERPREVIOUS; int currentLine = getCurrentLine(view); const int lineMax = ::SendMessage(view, SCI_GETLINECOUNT, 0, 0); const int prevLine = currentLine; int nextLine = currentLine; while (nextLine == currentLine) { if (down) { while ((::SendMessage(view, SCI_MARKERGET, currentLine, 0) & sci_search_mask) && (currentLine < lineMax)) ++currentLine; } else { while ((::SendMessage(view, SCI_MARKERGET, currentLine, 0) & sci_search_mask) && (currentLine > -1)) --currentLine; } nextLine = ::SendMessage(view, sci_marker_direction, currentLine, sci_search_mask); if (nextLine < 0) { if (!wrapAround) return; currentLine = down ? 0 : lineMax; nextLine = ::SendMessage(view, sci_marker_direction, currentLine, sci_search_mask); if (nextLine < 0) return; else break; } } if ((down && (nextLine < prevLine)) || (!down && (nextLine > prevLine))) { FLASHWINFO flashInfo; flashInfo.cbSize = sizeof(flashInfo); flashInfo.hwnd = nppData._nppHandle; flashInfo.uCount = 2; flashInfo.dwTimeout = 100; flashInfo.dwFlags = FLASHW_ALL; ::FlashWindowEx(&flashInfo); } ::SendMessage(view, SCI_ENSUREVISIBLEENFORCEPOLICY, nextLine, 0); ::SendMessage(view, SCI_GOTOLINE, nextLine, 0); }
void DocumentEditor::toggleComment(bool lineCommentPrefered_) { QsciLexer* l = lexer(); if(l == 0) return; QString comment = l->commentLine(); QStringList commentBlock = l->commentBlock(); if(comment.isEmpty() && commentBlock.isEmpty()){ qDebug() << "Toggle comment is not supported for " << l->language(); return; } if (!hasSelectedText()) { //if line is empty, skip it int line = getCurrentLine(); if (isLineEmpty(line)) return; QString selText = text(line); selText.remove("\n"); selText.remove("\r"); QString selTextTrimmed = selText.trimmed(); int pos_start = SendScintilla(SCI_POSITIONFROMLINE, line); int pos_end = SendScintilla(SCI_GETLINEENDPOSITION, line); // check for block comments on a line if(commentBlock.size() >= 2){ QString blockStart = commentBlock.first(); QString blockEnd = commentBlock.last(); if (selTextTrimmed.startsWith(blockStart) && selTextTrimmed.endsWith(blockEnd)) { beginUndoAction(); int idx1 = selText.indexOf(blockStart); selText.remove(idx1, blockEnd.size()); int idx2 = selText.lastIndexOf(blockEnd); selText.remove(idx2, blockEnd.size()); SendScintilla(SCI_SETTARGETSTART, pos_start); SendScintilla(SCI_SETTARGETEND, pos_end); SendScintilla(SCI_REPLACETARGET, -1, selText.toUtf8().data()); endUndoAction(); return; } } // check for single comments if (!comment.isEmpty()) { if (selTextTrimmed.startsWith(comment)) { // remove comment int idx = selText.indexOf(comment); selText = selText.remove(idx, comment.size()); } else { // set comment selText = selText.prepend(comment); } SendScintilla(SCI_SETTARGETSTART, pos_start); SendScintilla(SCI_SETTARGETEND, pos_end); SendScintilla(SCI_REPLACETARGET, -1, selText.toUtf8().data()); return; } }else{ // comment out the selection QString selText = selectedText(); QString selTextTrimmed = selText.trimmed(); if (selTextTrimmed.isEmpty()) return; int lineFrom, lineTo, indexFrom, indexTo; getSelection(&lineFrom, &indexFrom, &lineTo, &indexTo); int pos_start = positionFromLineIndex(lineFrom, indexFrom); int pos_end = positionFromLineIndex(lineTo, indexTo); // check if it is double commented block - to do before single check! if(commentBlock.size() >= 2){ QString blockStart = commentBlock.first(); QString blockEnd = commentBlock.last(); // comment exists? remove? if (selTextTrimmed.startsWith(blockStart) && selTextTrimmed.endsWith(blockEnd)) { beginUndoAction(); int idx1 = selText.indexOf(blockStart); selText.remove(idx1, blockStart.size()); int idx2 = selText.lastIndexOf(blockEnd); selText.remove(idx2, blockEnd.size()); SendScintilla(SCI_TARGETFROMSELECTION); SendScintilla(SCI_REPLACETARGET, -1, selText.toUtf8().data()); SendScintilla(SCI_SETSEL, SendScintilla(SCI_GETTARGETSTART), SendScintilla(SCI_GETTARGETEND)); endUndoAction(); return; } } // check if this block can be single commented if (!comment.isEmpty() && lineCommentPrefered_) { bool empty_start = false, empty_end = false; if (indexFrom == 0) empty_start = true; else empty_start = getTextRange(positionFromLineIndex(lineFrom, 0), pos_start).trimmed().isEmpty(); if (indexTo == 0) empty_end = true; else empty_end = getTextRange(pos_end, positionFromLineIndex(lineTo+1, 0)).trimmed().isEmpty(); if (empty_start && empty_end) { beginUndoAction(); // corrections if (indexTo == 0) lineTo--; if (isLineEmpty(lineFrom)) { lineFrom++; indexFrom = 0; } // a workaround: move cursor to the next line to replace EOL as well setSelection(lineFrom, 0, lineTo+1, 0); QStringList sl; for (int i = lineFrom; i <= lineTo; i++) sl += text(i); bool comm = false; for (int i = 0; i < sl.count(); i++) if (!sl.at(i).trimmed().startsWith(comment)) { comm = true; break; } for (int i = 0; i < sl.count(); i++) { if (comm) sl[i] = sl[i].prepend(comment); else { int idx = sl.at(i).indexOf(comment); sl[i] = sl[i].remove(idx, comment.size()); } } SendScintilla(SCI_TARGETFROMSELECTION); SendScintilla(SCI_REPLACETARGET, -1, sl.join("").toUtf8().data()); SendScintilla(SCI_SETSEL, SendScintilla(SCI_GETTARGETSTART), SendScintilla(SCI_GETTARGETEND)); endUndoAction(); return; } } // else, set double comment if(commentBlock.size() >= 2){ QString blockStart = commentBlock.first(); QString blockEnd = commentBlock.last(); beginUndoAction(); // last is first SendScintilla(SCI_INSERTTEXT, pos_end, blockEnd.toUtf8().data()); SendScintilla(SCI_INSERTTEXT, pos_start, blockStart.toUtf8().data()); // select everything if(lineFrom == lineTo) setSelection(lineFrom, indexFrom, lineTo, indexTo + blockStart.size() + blockEnd.size()); else setSelection(lineFrom, indexFrom, lineTo, indexTo + blockEnd.size()); endUndoAction(); return; } } }