Exemplo n.º 1
0
void ui() {
    glColor3f(1,1,1);
    if(selection) {
        glDisable(GL_DEPTH_TEST);
        glColor3f(1,0,0);
        caret(selected_point,0.03,0,0,0,true);
        glEnable(GL_DEPTH_TEST);
    }
    // draw logo
    if(logo.get()) {
        glPushMatrix();
        glDisable(GL_LIGHT1);
        glColor3f(1,0,0);
        const bounds_t& b = logo->get_bounds();
        glTranslatef(-b.centre.x,-b.centre.y,b.centre.z);
        glTranslatef(-1.2,0,0);
        glRotatef(90,0,1,0);
        logo->draw(0);
        glEnable(GL_LIGHT1);
        glPopMatrix();
    }
    static char fps[128];
    snprintf(fps,sizeof(fps),"%u fps, %d visible objects (of %u)",(unsigned)framerate.per_second(now()),visible_objects,(unsigned)world()->size());
    static ui_label_t* label = new ui_label_t("this is a test");
    //label->set_pos(vec2_t(10,10));
    label->set_text(fps);
    ui_mgr()->draw();
}
Exemplo n.º 2
0
void Editor::en_msgfilter( NMHDR *nmhdr,LRESULT *result ){
	if( locked || fmtBusy ){ *result=1;return; }

	*result=0;
	getSel();

	MSGFILTER *msg=(MSGFILTER*)nmhdr;


	if( msg->msg==WM_RBUTTONDOWN ){

		CPoint p( LOWORD(msg->lParam),HIWORD(msg->lParam) );

		ClientToScreen( &p );

		CMenu *menu=blitzIDE.mainFrame->GetMenu();

		CMenu *edit=menu->GetSubMenu(1);

		edit->TrackPopupMenu( TPM_LEFTALIGN,p.x,p.y,blitzIDE.mainFrame );

	}else if( msg->msg==WM_CHAR ){
		if( msg->wParam=='\t' ){
			bool holding_shift=GetAsyncKeyState( VK_SHIFT )&0x80000000;
			int lineStart=editCtrl.LineFromChar( selStart );
			int lineEnd=editCtrl.LineFromChar( selEnd-1 );
			if( lineEnd<=lineStart && !holding_shift ) return;
			editCtrl.HideSelection( true,false );
			if( holding_shift ){
				char buff[4];
				for( int line=lineStart;line<=lineEnd;++line ){
					int n=editCtrl.LineIndex( line );
					editCtrl.SetSel( n,n+1 );editCtrl.GetSelText( buff );
					if( buff[0]=='\t' ) editCtrl.ReplaceSel( "",true );
				}
			}else{
				for( int line=lineStart;line<=lineEnd;++line ){
					int n=editCtrl.LineIndex( line );
					editCtrl.SetSel( n,n );editCtrl.ReplaceSel( "\t",true );
				}
			}
			selStart=editCtrl.LineIndex( lineStart );
			selEnd=editCtrl.LineIndex( lineEnd+1 )-1;
			setSel();*result=1;
			editCtrl.HideSelection( false,false );
		}else if( msg->wParam==13 ){
			if( selStart!=selEnd ) return;
			int k;
			int ln=editCtrl.LineFromChar( selStart )-1;
			int pos=selStart-editCtrl.LineIndex( ln );
			string line=getLine( ln );if( pos>line.size() ) return;
			for( k=0;k<pos && line[k]=='\t';++k ){}
			line=line.substr( 0,k )+'\0';
			editCtrl.ReplaceSel( line.data(),true );
			*result=1;
		}
	}
	caret();
}
Exemplo n.º 3
0
FontDia::FontDia(QTextCursor* cursor, QWidget* parent)
        : KDialog(parent),
        m_cursor(cursor)
{
    //First find out if we have more than one charFormat in our selection. If so, m_initialFormat/m_style will get initialised with the charFormat at the cursor's position. The tabs will get informed of this.

    if (m_cursor->hasSelection()) {
        int begin = qMin(m_cursor->anchor(), m_cursor->position());
        int end = qMax(m_cursor->anchor(), m_cursor->position());
        QTextBlock block = m_cursor->block().document()->findBlock(begin);
        m_uniqueFormat = true;
        QTextCursor caret(*m_cursor);
        caret.setPosition(begin+1);
        m_initialFormat = caret.charFormat();
        while (block.isValid() && block.position() < end) {
            QTextBlock::iterator iter = block.begin();
            while (! iter.atEnd()) {
                QTextFragment fragment = iter.fragment();
                if (fragment.position() >= end)
                    break;
                if (fragment.position() + fragment.length() <= begin) {
                    iter++;
                    continue;
                }
                if (!(m_uniqueFormat = (fragment.charFormat() == m_initialFormat)))
                    break;
                iter++;
            }
            if (!m_uniqueFormat)
                break;
            block = block.next();
        }
    }
    else {
        m_initialFormat = cursor->charFormat();
        m_uniqueFormat = true;
    }

    setCaption(i18n("Select Font"));
    setModal(true);
    setButtons(Ok | Cancel | Reset | Apply);
    setDefaultButton(Ok);

    m_characterGeneral = new CharacterGeneral(this, m_uniqueFormat);
    m_characterGeneral->hideStyleName(true);
    setMainWidget(m_characterGeneral);

    connect(this, SIGNAL(applyClicked()), this, SLOT(slotApply()));
    connect(this, SIGNAL(okClicked()), this, SLOT(slotOk()));
    connect(this, SIGNAL(resetClicked()), this, SLOT(slotReset()));
    initTabs();
}
Exemplo n.º 4
0
void TextField::onDraw(sf::RenderTarget &target) const {
    sf::RectangleShape background(sf::Vector2f(width, height));
    background.setPosition(xPos, yPos);
    background.setFillColor(sf::Color(0, 0, 0, 128));
    background.setOutlineThickness(2);
    if (active) background.setOutlineColor(sf::Color(0, 0, 255, 255));
    else background.setOutlineColor(sf::Color(0, 0, 255, 128));
    target.draw(background);

    target.draw(title);

    if (active) {
        sf::RectangleShape caret(sf::Vector2f(2, title.getCharacterSize()));
        caret.setPosition(title.findCharacterPos(caretPos));
        caret.setFillColor(sf::Color(255, 255, 255));
        target.draw(caret);
    }
}
Exemplo n.º 5
0
void InsertDeleteChangesCommand::insertDeleteChanges()
{
    int numAddedChars = 0;
    QVector<KChangeTrackerElement *> elementVector;
    KTextDocument(m_document).changeTracker()->deletedChanges(elementVector);
    qSort(elementVector.begin(), elementVector.end(), isPositionLessThan);

    foreach (KChangeTrackerElement *element, elementVector) {
        if (element->isValid() && element->deleteChangeMarker()) {
            QTextCursor caret(element->deleteChangeMarker()->document());
            caret.setPosition(element->deleteChangeMarker()->position() + numAddedChars +  1);
            QTextCharFormat f = caret.charFormat();
            f.clearProperty(KCharacterStyle::InlineInstanceId);
            caret.setCharFormat(f);
            KChangeTracker::insertDeleteFragment(caret, element->deleteChangeMarker());
            numAddedChars += KChangeTracker::fragmentLength(element->deleteData());
        }
    }
}
Exemplo n.º 6
0
void RemoveDeleteChangesCommand::removeDeleteChanges()
{
    int numDeletedChars = 0;
    QVector<KChangeTrackerElement *> elementVector;
    KTextDocument(m_document).changeTracker()->getDeletedChanges(elementVector);
    qSort(elementVector.begin(), elementVector.end(), isPositionLessThan);

    foreach(KChangeTrackerElement *element, elementVector) {
        if (element->isValid() && element->getDeleteChangeMarker()) {
            QTextCursor caret(element->getDeleteChangeMarker()->document());
            QTextCharFormat f;
            int deletePosition = element->getDeleteChangeMarker()->position() + 1 - numDeletedChars;
            caret.setPosition(deletePosition);
            int deletedLength = KChangeTracker::fragmentLength(element->getDeleteData());
            caret.setPosition(deletePosition + deletedLength, QTextCursor::KeepAnchor);
            caret.removeSelectedText();
            numDeletedChars += KChangeTracker::fragmentLength(element->getDeleteData());
        }
    }
}
Exemplo n.º 7
0
		/// Gets the caret position
		bool textbox::caret_pos(point& pos, bool text_coordinate) const
		{
			auto editor = get_drawer_trigger().editor();
			internal_scope_guard lock;
			if (!editor)
				return false;

			auto scr_pos = editor->caret_screen_pos();

			if (text_coordinate)
			{
				auto upos = editor->caret();
				pos.x = static_cast<int>(upos.x);
				pos.y = static_cast<int>(upos.y);
			}
			else
				pos = scr_pos;

			return editor->hit_text_area(scr_pos);
		}
Exemplo n.º 8
0
bool Editor::setText( istream &in ){
//	editCtrl.HideCaret();
	fmtBusy=true;
	EDITSTREAM es;
	es.dwCookie=(DWORD)this;
	es.dwError=0;
	es.pfnCallback=streamIn;
	is_line="{\\rtf1\\ansi{{\\colortbl;"+rtfbgr(prefs.rgb_string)+rtfbgr(prefs.rgb_ident)+
	rtfbgr(prefs.rgb_keyword)+rtfbgr(prefs.rgb_comment)+rtfbgr(prefs.rgb_digit)+
	rtfbgr(prefs.rgb_default)+"}";
	int tabTwips=1440*8/GetDeviceCaps( ::GetDC(0),LOGPIXELSX ) * prefs.edit_tabs;
	for( int k=0;k<MAX_TAB_STOPS;++k ) is_line+="\\tx"+itoa( k*tabTwips )+' ';
	is_stream=&in;
	is_curs=is_linenum=0;
	funcList.clear();
	typeList.clear();
	labsList.clear();
	editCtrl.StreamIn( SF_RTF,es );
	fmtBusy=false;
//	editCtrl.HideCaret();
	caret();
	return es.dwError==0;
}
Exemplo n.º 9
0
		void parser_message(shared_ptr<c_parser> parser, string file, int line, string message, c_parser_diagnostic_kind kind) {
			if (kind == c_parser_diagnostic_kind::PARSER_DIAGNOSTIC_KIND_ERROR)
				msg(file, line, message);
			else if (kind == c_parser_diagnostic_kind::PARSER_DIAGNOSTIC_KIND_WARNING)
				warn(file, line, message);
			else if (kind == c_parser_diagnostic_kind::PARSER_DIAGNOSTIC_KIND_NOTE) {
				note(file, line, message);
				return;
			}
			else
				SEMANTICS_ASSERT(true && "c_parser_diagnostic_kind not detected (this should be unreachable).");
			if (kind == c_parser_diagnostic_kind::PARSER_DIAGNOSTIC_KIND_ERROR || kind == c_parser_diagnostic_kind::PARSER_DIAGNOSTIC_KIND_WARNING) {
				cerr << '\n' << '\n' << '\t';
				int limit = parser->pos;
				if (limit == parser->temporary_pos) limit++;
				for (int pos = parser->temporary_pos; pos < limit; pos++) {
					cerr << parser->token_list[pos]->get_qualifier() << ' ';
				}
				cerr << '\n' << '\n' << '\t';
				caret(1);
				cerr << '\n';
			}
		}
Exemplo n.º 10
0
void spatial_test() {
    enum { MIN_OBJS = 150, MAX_OBJS = 170, };
    glDisable(GL_TEXTURE_2D);
    for(int i=objs.size()-1; i>=0; i--) {
        test_t* obj = objs[i];
        glColor3ub(0xff,0,0);
        if(obj->is_visible()) {
            if(!world()->is_visible(*obj))
                std::cerr << *obj << " thinks it is visible but it isn't" << std::endl;
            else if(!obj->drawn)
                std::cerr << *obj << " thinks it is visible but wasn't drawn" << std::endl;
            else
                glColor3ub(0,0xff,0);
        } else {
            if(world()->is_visible(*obj))
                std::cerr << *obj << " thinks it is invisible but it is" << std::endl;
            else if(obj->drawn)
                std::cerr << *obj << " is invisible but was drawn" << std::endl;
            else
                glColor3ub(0,0,0xff);
        }
        obj->drawn = false;
        caret(obj->get_pos(),obj->SZ,obj->rx,obj->ry,obj->rz);
        if(!obj->tick()) {
            objs.erase(objs.begin()+i);
            delete obj;
        }
    }
    glEnable(GL_TEXTURE_2D);
    if(!objs.size() < MIN_OBJS) {
        const size_t n = MIN_OBJS+(rand()%(MAX_OBJS-MIN_OBJS));
        while(objs.size()<n) {
            objs.push_back(new test_t());
        }
    }
}
Exemplo n.º 11
0
void InsertTextCommand::input(const String& text, bool selectInsertedText, RebalanceType whitespaceRebalance)
{
    
    ASSERT(text.find('\n') == notFound);

    if (!endingSelection().isNonOrphanedCaretOrRange())
        return;

    // Delete the current selection.
    // FIXME: This delete operation blows away the typing style.
    if (endingSelection().isRange()) {
        if (performTrivialReplace(text, selectInsertedText))
            return;
        deleteSelection(false, true, true, false);
    }

    Position startPosition(endingSelection().start());
    
    Position placeholder;
    // We want to remove preserved newlines and brs that will collapse (and thus become unnecessary) when content 
    // is inserted just before them.
    // FIXME: We shouldn't really have to do this, but removing placeholders is a workaround for 9661.
    // If the caret is just before a placeholder, downstream will normalize the caret to it.
    Position downstream(startPosition.downstream());
    if (lineBreakExistsAtPosition(downstream)) {
        // FIXME: This doesn't handle placeholders at the end of anonymous blocks.
        VisiblePosition caret(startPosition);
        if (isEndOfBlock(caret) && isStartOfParagraph(caret))
            placeholder = downstream;
        // Don't remove the placeholder yet, otherwise the block we're inserting into would collapse before
        // we get a chance to insert into it.  We check for a placeholder now, though, because doing so requires
        // the creation of a VisiblePosition, and if we did that post-insertion it would force a layout.
    }
    
    // Insert the character at the leftmost candidate.
    startPosition = startPosition.upstream();
    
    // It is possible for the node that contains startPosition to contain only unrendered whitespace,
    // and so deleteInsignificantText could remove it.  Save the position before the node in case that happens.
    Position positionBeforeStartNode(positionInParentBeforeNode(startPosition.containerNode()));
    deleteInsignificantText(startPosition.upstream(), startPosition.downstream());
    if (!startPosition.anchorNode()->inDocument())
        startPosition = positionBeforeStartNode;
    if (!startPosition.isCandidate())
        startPosition = startPosition.downstream();
    
    startPosition = positionAvoidingSpecialElementBoundary(startPosition);
    
    Position endPosition;
    
    if (text == "\t") {
        endPosition = insertTab(startPosition);
        startPosition = endPosition.previous();
        if (placeholder.isNotNull())
            removePlaceholderAt(placeholder);
    } else {
        // Make sure the document is set up to receive text
        startPosition = positionInsideTextNode(startPosition);
        ASSERT(startPosition.anchorType() == Position::PositionIsOffsetInAnchor);
        ASSERT(startPosition.containerNode());
        ASSERT(startPosition.containerNode()->isTextNode());
        if (placeholder.isNotNull())
            removePlaceholderAt(placeholder);
        RefPtr<Text> textNode = static_cast<Text*>(startPosition.containerNode());
        const unsigned offset = startPosition.offsetInContainerNode();

        insertTextIntoNode(textNode, offset, text);
        endPosition = Position(textNode, offset + text.length());

        if (whitespaceRebalance == RebalanceLeadingAndTrailingWhitespaces) {
            // The insertion may require adjusting adjacent whitespace, if it is present.
            rebalanceWhitespaceAt(endPosition);
            // Rebalancing on both sides isn't necessary if we've inserted only spaces.
            if (!shouldRebalanceLeadingWhitespaceFor(text))
                rebalanceWhitespaceAt(startPosition);
        } else {
            ASSERT(whitespaceRebalance == RebalanceAllWhitespaces);
            if (canRebalance(startPosition) && canRebalance(endPosition))
                rebalanceWhitespaceOnTextSubstring(textNode, startPosition.offsetInContainerNode(), endPosition.offsetInContainerNode());
        }
    }

    // We could have inserted a part of composed character sequence,
    // so we are basically treating ending selection as a range to avoid validation.
    // <http://bugs.webkit.org/show_bug.cgi?id=15781>
    VisibleSelection forcedEndingSelection;
    forcedEndingSelection.setWithoutValidation(startPosition, endPosition);
    setEndingSelection(forcedEndingSelection);

    // Handle the case where there is a typing style.
    if (RefPtr<EditingStyle> typingStyle = document()->frame()->selection()->typingStyle()) {
        typingStyle->prepareToApplyAt(endPosition, EditingStyle::PreserveWritingDirection);
        if (!typingStyle->isEmpty())
            applyStyle(typingStyle.get());
    }

    if (!selectInsertedText)
        setEndingSelection(VisibleSelection(endingSelection().end(), endingSelection().affinity()));
}
Exemplo n.º 12
0
void Editor::en_selchange( NMHDR *nmhdr,LRESULT *result ){
	if( !fmtBusy ) fixFmt(false);
	cursorMoved();
	caret();
}
Exemplo n.º 13
0
void Editor::en_update(){
	caret();
}
Exemplo n.º 14
0
void Editor::OnSetFocus( CWnd *wnd ){
	if( prefs.edit_blkcursor ) SetCaretBlinkTime( 200 );
	editCtrl.SetFocus();
	caret();
}
void InsertTextCommand::input(const String& text, bool selectInsertedText)
{
    
    ASSERT(text.find('\n') == notFound);

    if (!endingSelection().isNonOrphanedCaretOrRange())
        return;

    // Delete the current selection.
    // FIXME: This delete operation blows away the typing style.
    if (endingSelection().isRange()) {
        if (performTrivialReplace(text, selectInsertedText))
            return;
        deleteSelection(false, true, true, false);
    }

    Position startPosition(endingSelection().start());
    
    Position placeholder;
    // We want to remove preserved newlines and brs that will collapse (and thus become unnecessary) when content 
    // is inserted just before them.
    // FIXME: We shouldn't really have to do this, but removing placeholders is a workaround for 9661.
    // If the caret is just before a placeholder, downstream will normalize the caret to it.
    Position downstream(startPosition.downstream());
    if (lineBreakExistsAtPosition(downstream)) {
        // FIXME: This doesn't handle placeholders at the end of anonymous blocks.
        VisiblePosition caret(startPosition);
        if (isEndOfBlock(caret) && isStartOfParagraph(caret))
            placeholder = downstream;
        // Don't remove the placeholder yet, otherwise the block we're inserting into would collapse before
        // we get a chance to insert into it.  We check for a placeholder now, though, because doing so requires
        // the creation of a VisiblePosition, and if we did that post-insertion it would force a layout.
    }
    
    // Insert the character at the leftmost candidate.
    startPosition = startPosition.upstream();
    
    // It is possible for the node that contains startPosition to contain only unrendered whitespace,
    // and so deleteInsignificantText could remove it.  Save the position before the node in case that happens.
    Position positionBeforeStartNode(positionInParentBeforeNode(startPosition.node()));
    deleteInsignificantText(startPosition.upstream(), startPosition.downstream());
    if (!startPosition.node()->inDocument())
        startPosition = positionBeforeStartNode;
    if (!startPosition.isCandidate())
        startPosition = startPosition.downstream();
    
    startPosition = positionAvoidingSpecialElementBoundary(startPosition);
    
    Position endPosition;
    
    if (text == "\t") {
        endPosition = insertTab(startPosition);
        startPosition = endPosition.previous();
        if (placeholder.isNotNull())
            removePlaceholderAt(placeholder);
        m_charactersAdded += 1;
    } else {
        // Make sure the document is set up to receive text
        startPosition = prepareForTextInsertion(startPosition);
        if (placeholder.isNotNull())
            removePlaceholderAt(placeholder);
        Text *textNode = static_cast<Text *>(startPosition.node());
        int offset = startPosition.deprecatedEditingOffset();

        insertTextIntoNode(textNode, offset, text);
        endPosition = Position(textNode, offset + text.length());

        // The insertion may require adjusting adjacent whitespace, if it is present.
        rebalanceWhitespaceAt(endPosition);
        // Rebalancing on both sides isn't necessary if we've inserted a space.
        if (text != " ") 
            rebalanceWhitespaceAt(startPosition);
            
        m_charactersAdded += text.length();
    }

    // We could have inserted a part of composed character sequence,
    // so we are basically treating ending selection as a range to avoid validation.
    // <http://bugs.webkit.org/show_bug.cgi?id=15781>
    VisibleSelection forcedEndingSelection;
    forcedEndingSelection.setWithoutValidation(startPosition, endPosition);
    setEndingSelection(forcedEndingSelection);

    // Handle the case where there is a typing style.
    CSSMutableStyleDeclaration* typingStyle = document()->frame()->selection()->typingStyle();
    RefPtr<CSSComputedStyleDeclaration> endingStyle = endPosition.computedStyle();
    RefPtr<CSSValue> unicodeBidi;
    RefPtr<CSSValue> direction;
    if (typingStyle) {
        unicodeBidi = typingStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi);
        direction = typingStyle->getPropertyCSSValue(CSSPropertyDirection);
    }
    endingStyle->diff(typingStyle);
    if (typingStyle && unicodeBidi) {
        ASSERT(unicodeBidi->isPrimitiveValue());
        typingStyle->setProperty(CSSPropertyUnicodeBidi, static_cast<CSSPrimitiveValue*>(unicodeBidi.get())->getIdent());
        if (direction) {
            ASSERT(direction->isPrimitiveValue());
            typingStyle->setProperty(CSSPropertyDirection, static_cast<CSSPrimitiveValue*>(direction.get())->getIdent());
        }
    }

    if (typingStyle && typingStyle->length())
        applyStyle(typingStyle);

    if (!selectInsertedText)
        setEndingSelection(VisibleSelection(endingSelection().end(), endingSelection().affinity()));
}
Exemplo n.º 16
-1
void InsertTextCommand::doApply()
{
    ASSERT(m_text.find('\n') == kNotFound);

    if (!endingSelection().isNonOrphanedCaretOrRange())
        return;

    // Delete the current selection.
    // FIXME: This delete operation blows away the typing style.
    if (endingSelection().isRange()) {
        if (performTrivialReplace(m_text, m_selectInsertedText))
            return;
        bool endOfSelectionWasAtStartOfBlock = isStartOfBlock(endingSelection().visibleEnd());
        deleteSelection(false, true, false, false);
        // deleteSelection eventually makes a new endingSelection out of a Position. If that Position doesn't have
        // a renderer (e.g. it is on a <frameset> in the DOM), the VisibleSelection cannot be canonicalized to
        // anything other than NoSelection. The rest of this function requires a real endingSelection, so bail out.
        if (endingSelection().isNone())
            return;
        if (endOfSelectionWasAtStartOfBlock) {
            if (EditingStyle* typingStyle = document().frame()->selection().typingStyle())
                typingStyle->removeBlockProperties();
        }
    } else if (document().frame()->editor().isOverwriteModeEnabled()) {
        if (performOverwrite(m_text, m_selectInsertedText))
            return;
    }

    Position startPosition(endingSelection().start());

    Position placeholder;
    // We want to remove preserved newlines and brs that will collapse (and thus become unnecessary) when content
    // is inserted just before them.
    // FIXME: We shouldn't really have to do this, but removing placeholders is a workaround for 9661.
    // If the caret is just before a placeholder, downstream will normalize the caret to it.
    Position downstream(startPosition.downstream());
    if (lineBreakExistsAtPosition(downstream)) {
        // FIXME: This doesn't handle placeholders at the end of anonymous blocks.
        VisiblePosition caret(startPosition);
        if (isEndOfBlock(caret) && isStartOfParagraph(caret))
            placeholder = downstream;
        // Don't remove the placeholder yet, otherwise the block we're inserting into would collapse before
        // we get a chance to insert into it.  We check for a placeholder now, though, because doing so requires
        // the creation of a VisiblePosition, and if we did that post-insertion it would force a layout.
    }

    // Insert the character at the leftmost candidate.
    startPosition = startPosition.upstream();

    // It is possible for the node that contains startPosition to contain only unrendered whitespace,
    // and so deleteInsignificantText could remove it.  Save the position before the node in case that happens.
    ASSERT(startPosition.containerNode());
    Position positionBeforeStartNode(positionInParentBeforeNode(*startPosition.containerNode()));
    deleteInsignificantText(startPosition, startPosition.downstream());
    if (!startPosition.inDocument())
        startPosition = positionBeforeStartNode;
    if (!startPosition.isCandidate())
        startPosition = startPosition.downstream();

    startPosition = positionAvoidingSpecialElementBoundary(startPosition);

    Position endPosition;

    if (m_text == "\t") {
        endPosition = insertTab(startPosition);
        startPosition = endPosition.previous();
        if (placeholder.isNotNull())
            removePlaceholderAt(placeholder);
    } else {
        // Make sure the document is set up to receive m_text
        startPosition = positionInsideTextNode(startPosition);
        ASSERT(startPosition.anchorType() == Position::PositionIsOffsetInAnchor);
        ASSERT(startPosition.containerNode());
        ASSERT(startPosition.containerNode()->isTextNode());
        if (placeholder.isNotNull())
            removePlaceholderAt(placeholder);
        RefPtrWillBeRawPtr<Text> textNode = startPosition.containerText();
        const unsigned offset = startPosition.offsetInContainerNode();

        insertTextIntoNode(textNode, offset, m_text);
        endPosition = Position(textNode, offset + m_text.length());

        if (m_rebalanceType == RebalanceLeadingAndTrailingWhitespaces) {
            // The insertion may require adjusting adjacent whitespace, if it is present.
            rebalanceWhitespaceAt(endPosition);
            // Rebalancing on both sides isn't necessary if we've inserted only spaces.
            if (!shouldRebalanceLeadingWhitespaceFor(m_text))
                rebalanceWhitespaceAt(startPosition);
        } else {
            ASSERT(m_rebalanceType == RebalanceAllWhitespaces);
            if (canRebalance(startPosition) && canRebalance(endPosition))
                rebalanceWhitespaceOnTextSubstring(textNode, startPosition.offsetInContainerNode(), endPosition.offsetInContainerNode());
        }
    }

    setEndingSelectionWithoutValidation(startPosition, endPosition);

    // Handle the case where there is a typing style.
    if (RefPtrWillBeRawPtr<EditingStyle> typingStyle = document().frame()->selection().typingStyle()) {
        typingStyle->prepareToApplyAt(endPosition, EditingStyle::PreserveWritingDirection);
        if (!typingStyle->isEmpty())
            applyStyle(typingStyle.get());
    }

    if (!m_selectInsertedText)
        setEndingSelection(VisibleSelection(endingSelection().end(), endingSelection().affinity(), endingSelection().isDirectional()));
}