void KDocumentTextBuffer::onEraseText( unsigned int offset, unsigned int length, QInfinity::User *user ) { if ( m_aboutToClose ) return; if( !blockRemoteRemove ) { kDebug() << "REMOTE ERASE TEXT len" << length << "offset" << offset << kDocument()->url(); KTextEditor::Cursor startCursor = offsetRelativeTo_kte(KTextEditor::Cursor(0, 0), offset); KTextEditor::Cursor endCursor = offsetRelativeTo_kte(startCursor, length); KTextEditor::Range range = KTextEditor::Range(startCursor, endCursor); ReadWriteTransaction transaction(kDocument()); #ifdef KTEXTEDITOR_HAS_BUFFER_IFACE // see onInsertText if ( KTextEditor::BufferInterface* iface = qobject_cast<KTextEditor::BufferInterface*>(kDocument()) ) { iface->removeTextSilent(KTextEditor::Range(startCursor, endCursor)); } #else if ( false ) { } #endif else { kDocument()->blockSignals(true); kDocument()->removeText( range ); kDocument()->blockSignals(false); } emit remoteChangedText(range, user, true); checkConsistency(); } else blockRemoteRemove = false; }
unsigned int KDocumentTextBuffer::cursorToOffset_kte( const KTextEditor::Cursor &cursor ) { unsigned int offset = 0; for( int i = 0; i < cursor.line(); i++ ) { offset += countUnicodeCharacters(kDocument()->line(i)) + 1; // Add newline } offset += countUnicodeCharacters(kDocument()->line(cursor.line()).left(cursor.column())); return offset; }
void KDocumentTextBuffer::localTextRemoved( KTextEditor::Document *document, const KTextEditor::Range &range, const QString& oldText ) { if ( m_aboutToClose ) return; kDebug() << "local text removed:" << kDocument() << range; emit localChangedText(range, user(), true); Q_UNUSED(document) textOpPerformed(); if( !m_user.isNull() ) { unsigned int offset = cursorToOffset_kte( range.start() ); unsigned int len = countUnicodeCharacters(oldText); blockRemoteRemove = true; kDebug() << "ERASING TEXT" << oldText << "with len" << len << "offset" << offset << "range" << range; kDebug() << offset << len << length(); if( len > 0 ) eraseText( offset, len, m_user ); else kDebug() << "0 legth delete operation. Skipping."; checkConsistency(); } else kDebug() << "Could not remove text: No local user set."; }
void KDocumentTextBuffer::checkLineEndings() { QString bufferContents = kDocument()->text(); if ( bufferContents.contains("\r\n") || bufferContents.contains("\r") ) { KDialog* dlg = new KDialog(kDocument()->activeView()); dlg->setAttribute(Qt::WA_DeleteOnClose); dlg->setButtons(KDialog::Ok | KDialog::Cancel); dlg->button(KDialog::Ok)->setText(i18n("Continue")); QLabel* l = new QLabel(i18n("The document you opened contains non-standard line endings. " "Do you want to convert them to the standard \"\\n\" format?<br><br>" "<i>Note: This change will be synchronized to the server.</i>"), dlg); l->setWordWrap(true); dlg->setMainWidget(l); connect(dlg, SIGNAL(okClicked()), this, SLOT(replaceLineEndings())); dlg->show(); } }
void KDocumentTextBuffer::localTextInserted( KTextEditor::Document *document, const KTextEditor::Range &range ) { if ( m_aboutToClose ) return; emit localChangedText(range, user(), false); Q_UNUSED(document) textOpPerformed(); if( m_user.isNull() ) { kDebug() << "Could not insert text: No local user set."; return; } unsigned int offset = cursorToOffset_kte(range.start()); kDebug() << "local text inserted" << kDocument() << "( range" << range << ")" << m_user << "offset:" << offset; QInfinity::TextChunk chunk(encoding()); QString text = kDocument()->text(range); #ifdef ENABLE_TAB_HACK if ( text.contains('\t') ) { text = text.replace('\t', " "); kDocument()->blockSignals(true); kDocument()->replaceText(range, text); kDocument()->blockSignals(false); } #endif Q_ASSERT(encoder()); if ( text.isEmpty() ) { kDebug() << "Skipping empty insert."; return; } QByteArray encodedText = codec()->fromUnicode( text ); if ( encodedText.size() == 0 ) { kDebug() << "Got empty encoded text from non empty string " "Skipping insertion"; } else { chunk.insertText( 0, encodedText, countUnicodeCharacters(text), m_user->id() ); blockRemoteInsert = true; kDebug() << "inserting chunk of size" << chunk.length() << "into local buffer" << kDocument()->url(); insertChunk( offset, chunk, m_user ); kDebug() << "done inserting chunk"; checkConsistency(); } }
/* Accepting the session and buffer as parameters, although we could obtain them from the session proxy, ensures some type safety. */ InfTextDocument::InfTextDocument( QInfinity::SessionProxy* proxy, QInfinity::TextSession* session, KDocumentTextBuffer* buffer, const QString &name ) : Document( buffer->kDocument() ) , m_sessionProxy( proxy ) , m_session( session ) , m_buffer( buffer ) , m_user( 0 ) , m_name( name ) { kDebug() << "new infTextDocument for url" << kDocument()->url(); m_session->setParent( this ); m_sessionProxy->setParent( this ); connect( kDocument(), SIGNAL(viewCreated( KTextEditor::Document*, KTextEditor::View* )), this, SLOT(slotViewCreated( KTextEditor::Document*, KTextEditor::View* )) ); foreach ( KTextEditor::View* view, kDocument()->views() ) { slotViewCreated(kDocument(), view); }
KTextEditor::Cursor KDocumentTextBuffer::offsetRelativeTo_kte(const KTextEditor::Cursor& cursor, unsigned int offset) { int lineno = cursor.line(); const QString& firstLine = kDocument()->line(lineno).mid(cursor.column()); unsigned int remaining = offset; int surrogates = surrogatesForCodePoints(firstLine, remaining); while ( remaining > 0 ) { remaining -= 1; // for the newline character lineno += 1; if ( remaining == 0 ) { surrogates = 0; break; } const QString& line = kDocument()->line(lineno); Q_ASSERT( lineno < kDocument()->lines() ); surrogates = surrogatesForCodePoints(line, remaining); } return KTextEditor::Cursor(lineno, lineno == cursor.line() ? cursor.column() + surrogates : surrogates); }
void KDocumentTextBuffer::checkConsistency() { QString bufferContents = codec()->toUnicode( slice(0, length())->text() ); QString documentContents = kDocument()->text(); if ( bufferContents != documentContents ) { KUrl url = kDocument()->url(); kDocument()->setModified(false); kDocument()->setReadWrite(false); m_aboutToClose = true; QTemporaryFile f; f.setAutoRemove(false); f.open(); f.close(); kDocument()->saveAs(f.fileName()); KDialog* dialog = new KDialog; dialog->setButtons(KDialog::Ok | KDialog::Cancel); QLabel* label = new QLabel(i18n("Sorry, an internal error occurred in the text synchronization component.<br>" "You can try to reload the document or disconnect.")); label->setWordWrap(true); dialog->setMainWidget(label); dialog->button(KDialog::Ok)->setText(i18n("Reload document")); dialog->button(KDialog::Cancel)->setText(i18n("Disconnect")); DocumentReopenHelper* helper = new DocumentReopenHelper(url, kDocument()); connect(dialog, SIGNAL(accepted()), helper, SLOT(reopen())); // We must not use exec() here, since that will create a nested event loop, // which might handle incoming network events. This can easily get very messy. dialog->show(); } }
void KDocumentTextBuffer::replaceLineEndings() { const QStringList lines = kDocument()->textLines( KTextEditor::Range( KTextEditor::Cursor::start(), KTextEditor::Cursor(kDocument()->lines(), kDocument()->lineLength(kDocument()->lines() - 1) )) ); for ( int i = lines.count() - 1; i >= 0; i-- ) { QString line = lines[i]; int offset = 0; while ( ( offset = line.lastIndexOf('\r') ) != -1 ) { int replaceLen = 1; if ( offset - 1 < line.length() ) { // check if this \r is part of a \r\n if ( line[offset+1] == '\n' ) { replaceLen = 2; } } KTextEditor::Cursor replaceStart(i, offset); KTextEditor::Cursor replaceEnd(i, offset+replaceLen); KTextEditor::Range replaceRange = KTextEditor::Range(replaceStart, replaceEnd); kDocument()->replaceText(replaceRange, "\n"); line.replace(offset, replaceLen, '\n'); } } }
bool CConverToMK::ParseVCProjectFile() { for (ModuleInfoMap::iterator it = m_kModuleInfoMap.begin(); it != m_kModuleInfoMap.end();it++) { ModuleInfo kInfo = it->second; StringVector kVector; TiXmlDocument kDocument(kInfo.szVCProjFile); if (!kDocument.LoadFile()) { return false; } TiXmlElement* pkRootElement = kDocument.RootElement(); if (0 == pkRootElement) { return false; } TiXmlElement* pkFiles = pkRootElement->FirstChildElement("Files"); if (0 == pkFiles) { return false; } ParseFilterInVCProjectFile(pkFiles,kVector); m_kFilesPathData.insert(make_pair(string(kInfo.szModuleName),kVector)); } return true; }
void KDocumentTextBuffer::onInsertText( unsigned int offset, const QInfinity::TextChunk &chunk, QInfinity::User *user ) { if ( m_aboutToClose ) return; if( !blockRemoteInsert ) { kDebug() << "REMOTE INSERT TEXT offset" << offset << kDocument() << "(" << chunk.length() << " chars )" << kDocument()->url(); KTextEditor::Cursor startCursor = offsetToCursor_kte( offset ); QString str = codec()->toUnicode( chunk.text() ); ReadWriteTransaction transaction(kDocument()); kDocument()->blockSignals(true); kDocument()->insertText( startCursor, str ); kDocument()->blockSignals(false); Q_ASSERT(!qobject_cast<KTextEditor::ConfigInterface*>(kDocument())->configValue("replace-tabs").toBool()); emit remoteChangedText(KTextEditor::Range(startCursor, offsetToCursor_kte(offset+chunk.length())), user, false); checkConsistency(); } else blockRemoteInsert = false; }
CConverToMK::CConverToMK(const char* pszXMLFile): m_bIsInit(false), m_pszMKFile(0), m_pszHelpFile(0), m_pszConfigFile(0), m_uiKeyStringPosition(0) { m_pszMKFile = new char[255]; m_pszHelpFile = new char[255]; m_pszConfigFile = new char[255]; memset(m_pszHelpFile,0,sizeof(char) * 255); memset(m_pszMKFile,0,sizeof(char) * 255); memset(m_pszConfigFile,0,sizeof(char) * 255); TiXmlDocument kDocument(pszXMLFile); if (!kDocument.LoadFile()) { return; } TiXmlElement* pkConfElement = kDocument.RootElement(); if (0 == pkConfElement) { return; } TiXmlElement* pkSubElement = pkConfElement->FirstChildElement("module"); do { TiXmlAttribute* pkNameAttribute = pkSubElement->FirstAttribute(); string strName = pkNameAttribute->Name(); string strData; if (strcmp("name",strName.c_str()) != 0) { continue; } strData = pkNameAttribute->Value(); ModuleInfo kInfo = {0}; strcpy_s(kInfo.szModuleName,255,strData.c_str()); TiXmlElement* pkVCProjectPath = pkSubElement->FirstChildElement("VCProjectPath"); if (0 == pkVCProjectPath) { continue; } string strVCPath = pkVCProjectPath->GetText(); strcpy_s(kInfo.szVCProjFile,255,strVCPath.c_str()); crc_32_type kCrc32; kCrc32.process_bytes(kInfo.szModuleName,strlen(kInfo.szModuleName)); unsigned int uiID = kCrc32.checksum(); m_kModuleInfoMap.insert(make_pair(uiID,kInfo)); } while (pkSubElement = pkSubElement->NextSiblingElement("module")); TiXmlElement* pkPathElement = pkConfElement->FirstChildElement("path"); if (0 == pkPathElement) { return; } TiXmlElement* pkMKFilePath = pkPathElement->FirstChildElement("MKFilePath"); TiXmlElement* pkHelpFilePath = pkPathElement->FirstChildElement("HelpFilePath"); string strHelpFile = pkHelpFilePath->GetText(); string strMKFile = pkMKFilePath->GetText(); TiXmlElement* pkFilterElement = pkConfElement->FirstChildElement("filter"); if (pkFilterElement) { TiXmlElement* pkSrcFileElement = pkFilterElement->FirstChildElement("SrcFile"); do { string strTemp = pkSrcFileElement->GetText(); m_kFilterWord.push_back(strTemp); } while (pkSrcFileElement = pkSrcFileElement->NextSiblingElement("SrcFile")); } if (strHelpFile.length() != 0) { strcpy_s(m_pszHelpFile,255,strHelpFile.c_str()); if (!InitialiseHelp()) { return; } } if (0 == strMKFile.c_str()) { return; } strcpy_s(m_pszMKFile,255,strMKFile.c_str()); if (!ParseVCProjectFile()) { return; } if (!ParseMKFile()) { return; } m_bIsInit = true; }