Example #1
0
void SubassemblyView::updateConstraintName ( const QString& /*name*/ )
{
  // The budget approach is just to recompute all of the list view strings.
  // Not sure what being more selective would avail us.
  //ListViewItem* list_item = list_view_item_->firstChild();

    //TODO
    ListViewItem* list_item = static_cast<ListViewItem*>(list_view_item_->child(0));
   QListIterator< std::shared_ptr<AssemblyConstraint>> constraint = subassembly_->constraints().
                           constraints();

  while ( constraint.hasNext() ) {
    QString text;
    if ( constraint.peekNext()->type() == lC::STR::MATE_OFFSET ||
     constraint.peekNext()->type() == lC::STR::ALIGN_OFFSET )
      text = tr( "Offset %1: " ).
    arg( UnitsBasis::instance()->format( constraint.peekNext()->offset(),false));

    if ( constraint.peekNext()->reference1().empty() ) {
      text += lC::formatName( model()->idPath( constraint.peekNext()->reference0()));
    }
    else {
      text += tr( "%1 to %2" ).
    arg( lC::formatName( model()->idPath( constraint.peekNext()->reference0()))).
    arg( lC::formatName( model()->idPath( constraint.peekNext()->reference1())));
    }

    list_item->setData( text, lC::DETAIL );
//TODO
    //list_item = list_item->nextSibling();
  }
}
Example #2
0
/*
The ultimate line painting function.
Currently missing features:
- draw indent lines
*/
void KateRenderer::paintTextLine(QPainter& paint, KateLineLayoutPtr range, int xStart, int xEnd, const KTextEditor::Cursor* cursor)
{
  Q_ASSERT(range->isValid());

//   kDebug( 13033 )<<"KateRenderer::paintTextLine";

  // font data
  const QFontMetricsF &fm = config()->fontMetrics();

  int currentViewLine = -1;
  if (cursor && cursor->line() == range->line())
    currentViewLine = range->viewLineForColumn(cursor->column());

  paintTextLineBackground(paint, range, currentViewLine, xStart, xEnd);

  if (range->layout()) {
    bool drawSelection = m_view->selection() && showSelections() && m_view->selectionRange().overlapsLine(range->line());
    // Draw selection in block selecton mode. We need 2 kinds of selections that QTextLayout::draw can't render:
    //   - past-end-of-line selection and
    //   - 0-column-wide selection (used to indicate where text will be typed)
    if (drawSelection && m_view->blockSelection()) {
      int selectionStartColumn = m_doc->fromVirtualColumn(range->line(), m_doc->toVirtualColumn(m_view->selectionRange().start()));
      int selectionEndColumn   = m_doc->fromVirtualColumn(range->line(), m_doc->toVirtualColumn(m_view->selectionRange().end()));
      QBrush selectionBrush = config()->selectionColor();
      if (selectionStartColumn != selectionEndColumn) {
        KateTextLayout lastLine = range->viewLine(range->viewLineCount() - 1);
        if (selectionEndColumn > lastLine.startCol()) {
          int selectionStartX = (selectionStartColumn > lastLine.startCol()) ? cursorToX(lastLine, selectionStartColumn, true) : 0;
          int selectionEndX = cursorToX(lastLine, selectionEndColumn, true);
          paint.fillRect(QRect(selectionStartX - xStart, (int)lastLine.lineLayout().y(), selectionEndX - selectionStartX, lineHeight()), selectionBrush);
        }
      } else {
        const int selectStickWidth = 2;
        KateTextLayout selectionLine = range->viewLine(range->viewLineForColumn(selectionStartColumn));
        int selectionX = cursorToX(selectionLine, selectionStartColumn, true);
        paint.fillRect(QRect(selectionX - xStart, (int)selectionLine.lineLayout().y(), selectStickWidth, lineHeight()), selectionBrush);
      }
    }

    QVector<QTextLayout::FormatRange> additionalFormats;
    if (range->length() > 0) {
      // We may have changed the pen, be absolutely sure it gets set back to
      // normal foreground color before drawing text for text that does not
      // set the pen color
      paint.setPen(attribute(KTextEditor::HighlightInterface::dsNormal)->foreground().color());
      // Draw the text :)
      if (drawSelection) {
        // FIXME toVector() may be a performance issue
        additionalFormats = decorationsForLine(range->textLine(), range->line(), true).toVector();
        range->layout()->draw(&paint, QPoint(-xStart,0), additionalFormats);

      } else {
        range->layout()->draw(&paint, QPoint(-xStart,0));
      }
    }

    QBrush backgroundBrush;
    bool backgroundBrushSet = false;

    // Loop each individual line for additional text decoration etc.
    QListIterator<QTextLayout::FormatRange> it = range->layout()->additionalFormats();
    QVectorIterator<QTextLayout::FormatRange> it2 = additionalFormats;
    for (int i = 0; i < range->viewLineCount(); ++i) {
      KateTextLayout line = range->viewLine(i);

      // Determine the background to use, if any, for the end of this view line
      backgroundBrushSet = false;
      while (it2.hasNext()) {
        const QTextLayout::FormatRange& fr = it2.peekNext();
        if (fr.start > line.endCol())
          break;

        if (fr.start + fr.length > line.endCol()) {
          if (fr.format.hasProperty(QTextFormat::BackgroundBrush)) {
            backgroundBrushSet = true;
            backgroundBrush = fr.format.background();
          }

          goto backgroundDetermined;
        }

        it2.next();
      }

      while (it.hasNext()) {
        const QTextLayout::FormatRange& fr = it.peekNext();
        if (fr.start > line.endCol())
          break;

        if (fr.start + fr.length > line.endCol()) {
          if (fr.format.hasProperty(QTextFormat::BackgroundBrush)) {
            backgroundBrushSet = true;
            backgroundBrush = fr.format.background();
          }

          break;
        }

        it.next();
      }

      backgroundDetermined:

      // Draw selection or background color outside of areas where text is rendered
      if (!m_printerFriendly ) {
        bool draw = false;
        QBrush drawBrush;
        if (m_view->selection() && !m_view->blockSelection() && m_view->lineEndSelected(line.end(true))) {
          draw = true;
          drawBrush = config()->selectionColor();
        } else if (backgroundBrushSet && !m_view->blockSelection()) {
          draw = true;
          drawBrush = backgroundBrush;
        }

        if (draw) {
          int fillStartX = line.endX() - line.startX() + line.xOffset() - xStart;
          int fillStartY = lineHeight() * i;
          int width= xEnd - xStart - fillStartX;
          int height= lineHeight();

          // reverse X for right-aligned lines
          if (range->layout()->textOption().alignment() == Qt::AlignRight)
            fillStartX = 0;

          if (width > 0) {
            QRect area(fillStartX, fillStartY, width, height);
            paint.fillRect(area, drawBrush);
          }
        }
      }
      // Draw indent lines
      if (showIndentLines() && i == 0)
      {
        const qreal w = spaceWidth();
        const int lastIndentColumn = range->textLine()->indentDepth(m_tabWidth);

        for (int x = m_indentWidth; x < lastIndentColumn; x += m_indentWidth)
        {
          paintIndentMarker(paint, x * w + 1 - xStart, range->line());
        }
      }

      // draw an open box to mark non-breaking spaces
      const QString& text = range->textLine()->string();
      int y = lineHeight() * i + fm.ascent() - fm.strikeOutPos();
      int nbSpaceIndex = text.indexOf(nbSpaceChar, line.lineLayout().xToCursor(xStart));

      while (nbSpaceIndex != -1 && nbSpaceIndex < line.endCol()) {
        int x = line.lineLayout().cursorToX(nbSpaceIndex);
        if (x > xEnd)
          break;
        paintNonBreakSpace(paint, x - xStart, y);
        nbSpaceIndex = text.indexOf(nbSpaceChar, nbSpaceIndex + 1);
      }

      // draw tab stop indicators
      if (showTabs()) {
        int tabIndex = text.indexOf(tabChar, line.lineLayout().xToCursor(xStart));
        while (tabIndex != -1 && tabIndex < line.endCol()) {
          int x = line.lineLayout().cursorToX(tabIndex);
          if (x > xEnd)
            break;
          paintTabstop(paint, x - xStart + spaceWidth()/2.0, y);
          tabIndex = text.indexOf(tabChar, tabIndex + 1);
        }
      }

      // draw trailing spaces
      if (showTrailingSpaces()) {
        int spaceIndex = line.endCol() - 1;
        int trailingPos = range->textLine()->lastChar();
        if (trailingPos < 0)
          trailingPos = 0;
        if (spaceIndex >= trailingPos) {
          while (spaceIndex >= line.startCol() && text.at(spaceIndex).isSpace()) {
            if (text.at(spaceIndex) != '\t' || !showTabs())
              paintTrailingSpace(paint, line.lineLayout().cursorToX(spaceIndex) - xStart + spaceWidth()/2.0, y);
            --spaceIndex;
          }
        }
      }
    }

    // draw word-wrap-honor-indent filling
    if ( (range->viewLineCount() > 1)  && range->shiftX() && (range->shiftX() > xStart) )
    {
      if (backgroundBrushSet)
        paint.fillRect(0, lineHeight(), range->shiftX() - xStart, lineHeight() * (range->viewLineCount() - 1),
          backgroundBrush);
      paint.fillRect(0, lineHeight(), range->shiftX() - xStart, lineHeight() * (range->viewLineCount() - 1),
        QBrush(config()->wordWrapMarkerColor(), Qt::Dense4Pattern));
    }

    // Draw caret
    if (drawCaret() && cursor && range->includesCursor(*cursor)) {
      int caretWidth, lineWidth = 2;
      QColor color;
      QTextLine line = range->layout()->lineForTextPosition(qMin(cursor->column(), range->length()));

      // Determine the caret's style
      caretStyles style = caretStyle();

      // Make the caret the desired width
      if (style == Line) {
        caretWidth = lineWidth;
      } else if (line.isValid() && cursor->column() < range->length()) {
        caretWidth = int(line.cursorToX(cursor->column() + 1) - line.cursorToX(cursor->column()));
        if (caretWidth < 0) {
          caretWidth = -caretWidth;
        }
      } else {
        caretWidth = spaceWidth();
      }

      // Determine the color
      if (m_caretOverrideColor.isValid()) {
        // Could actually use the real highlighting system for this...
        // would be slower, but more accurate for corner cases
        color = m_caretOverrideColor;
      } else {
        // search for the FormatRange that includes the cursor
        foreach (const QTextLayout::FormatRange &r, range->layout()->additionalFormats()) {
          if ((r.start <= cursor->column() ) && ( (r.start + r.length)  > cursor->column())) {
            // check for Qt::NoBrush, as the returned color is black() and no invalid QColor
            QBrush foregroundBrush = r.format.foreground();
            if (foregroundBrush != Qt::NoBrush) {
              color = r.format.foreground().color();
            }
            break;
          }
        }
        // still no color found, fall back to default style
        if (!color.isValid())
          color = attribute(KTextEditor::HighlightInterface::dsNormal)->foreground().color();
      }

      // Clip the caret - Qt's caret has a habit of intruding onto other lines.
      paint.save();
      paint.setClipRect(0, line.lineNumber() * lineHeight(), xEnd - xStart, lineHeight());
      switch(style) {
      case Line :
        paint.setPen(QPen(color, caretWidth));
        break;
      case Block :
        // use a gray caret so it's possible to see the character
        color.setAlpha(128);
        paint.setPen(QPen(color, caretWidth));
        break;
      case Underline :
        paint.setClipRect(0, lineHeight() - lineWidth, xEnd - xStart, lineWidth);
        break;
      case Half :
        color.setAlpha(128);
        paint.setPen(QPen(color, caretWidth));
        paint.setClipRect(0, lineHeight() / 2, xEnd - xStart, lineHeight() / 2);
        break;
      }

      if (cursor->column() <= range->length()) {
        range->layout()->drawCursor(&paint, QPoint(-xStart,0), cursor->column(), caretWidth);
      } else {
        // Off the end of the line... must be block mode. Draw the caret ourselves.
        const KateTextLayout& lastLine = range->viewLine(range->viewLineCount() - 1);
        int x = cursorToX(lastLine, KTextEditor::Cursor(range->line(), cursor->column()), true);
        if ((x >= xStart) && (x <= xEnd)) {
          paint.fillRect(x - xStart, (int)lastLine.lineLayout().y(), caretWidth, lineHeight(), color);
        }
      }

      paint.restore();
    }
Example #3
0
void SubassemblyView::init ( void )
{
  setObjectName( subassembly_->name().toLatin1() );

  drawer_ = Space3D::OCSubassemblyDrawFactory::drawer( subassembly_, view() );

  modify_input_ = new SubassemblyModifyInput( this );

  dimensions_[0] = dimensions_[1] = dimensions_[2] = 0;

  dimension_name_ = view()->genSelectionName();

  ListViewItem* previous_item = parent()->previousItem( parent()->listViewItem(),
							 subassembly_->id() );

  list_view_item_ = new ListViewItem( parent()->listViewItem(), previous_item );

  list_view_item_->setData( lC::formatName( subassembly_->name() )
                + QString( " <%1>" ).arg( subassembly_->id() ),
                            lC::NAME );
  list_view_item_->setData( trC( subassembly_->type() ), lC::TYPE );
  list_view_item_->setData( tr( "Model: %1.%2 <%3>" ).
		    arg( lC::formatName( subassembly_->subassembly()->name()) ).
		    arg( trC( subassembly_->subassembly()->type() ) ).
            arg( lC::idToString( subassembly_->subassembly()->ID() ) ),
                            lC::DETAIL );
  //TODO
  //list_view_item_->listView()->ensureItemVisible( list_view_item_ );

  QListIterator<std::shared_ptr<AssemblyConstraint>> constraint =
    subassembly_->constraints().constraints();

  ListViewItem* constraint_item = 0;
  while ( constraint.hasNext() ) {
    constraint_item = new ListViewItem( list_view_item_, constraint_item );
    constraint_item->setData( trC( lC::STR::CONSTRAINT ), lC::NAME );
    constraint_item->setData( trC( constraint.peekNext()->type() ), lC::TYPE );
    constraint_item->setData( QVariant(), lC::DETAIL );

    updateChangedConstraint( 0, constraint.peekNext().get() );

    // Are there any offset constraints which need dimensions?
    if ( constraint.peekNext()->type() == lC::STR::MATE_OFFSET ||
     constraint.peekNext()->type() == lC::STR::ALIGN_OFFSET )
      updateChangedOffset( constraint.peekNext().get() );
    constraint.next();
  }

#if 0
  connect( subassembly_, SIGNAL( locationChanged() ), SLOT( updateLocation() ) );
  connect( subassembly_, SIGNAL( solidChanged() ), SLOT( updateTessellation() ) );
#else
  connect( subassembly_, SIGNAL( locationChanged() ), SLOT( updateTessellation() ) );
#endif
  connect( subassembly_, SIGNAL( materialChanged() ), SLOT( updateMaterial() ) );

  connect( subassembly_, SIGNAL( constraintCreated( const AssemblyConstraint*) ),
	   SLOT( updateNewConstraint( const AssemblyConstraint* ) ) );
  connect( subassembly_, SIGNAL( constraintChanged( const AssemblyConstraint*,
						    const AssemblyConstraint*) ),
	   SLOT( updateChangedConstraint( const AssemblyConstraint*,
					  const AssemblyConstraint* ) ) );
  connect( subassembly_, SIGNAL( constraintOffsetChanged( const AssemblyConstraint*) ),
	   SLOT( updateChangedOffset( const AssemblyConstraint* ) ) );

 connect( subassembly_, SIGNAL( constraintCanceled() ),
	   SLOT( updateCanceledConstraint() ) );

  connect( subassembly_->subassembly(), SIGNAL( nameChanged(const QString&) ),
	   SLOT( updateModelName( const QString& ) ) );

  connect( parent(), SIGNAL( orientationChanged( const GLdouble* ) ),
	   SLOT( updateViewNormal( const GLdouble* ) ) );

  if ( offset_info_dialog_ == 0 )
    offset_info_dialog_ = new OffsetInfoDialog( parent()->lCMW() );
}