void FileTabManager::open(const SmartPointer<Project::File> &file,
                          int line, int col) {
  // Check if we already have this file open in a tab
  unsigned tab;
  for (tab = offset; tab < (unsigned)QTabWidget::count(); tab++)
    if (getFile(tab) == file) break;

  // Create new tab
  if ((unsigned)QTabWidget::count() <= tab) {
    SmartPointer<Highlighter> highlighter;
    if (file->isTPL()) highlighter = new TPLHighlighter;
    else highlighter = new GCodeHighlighter;

    QApplication::setOverrideCursor(Qt::WaitCursor);
    NCEdit *editor = new NCEdit(file, highlighter, this);

    QFile qFile(QString::fromUtf8(file->getPath().c_str()));
    qFile.open(QFile::ReadOnly);
    QString contents = qFile.readAll();
    qFile.close();
    contents.replace('\t', "  ");

    editor->loadDarkScheme();
    editor->setWordWrapMode(QTextOption::NoWrap);
    editor->setPlainText(contents);

    connect(editor, SIGNAL(find()), SIGNAL(find()));
    connect(editor, SIGNAL(findNext()), SIGNAL(findNext()));
    connect(editor, SIGNAL(findResult(bool)), SIGNAL(findResult(bool)));

    QString title = QString::fromUtf8(file->getBasename().c_str());
    tab = (unsigned)QTabWidget::addTab(editor, title);
    QApplication::restoreOverrideCursor();
  }

  // Get editor
  NCEdit *editor = (NCEdit *)QTabWidget::widget(tab);

  // Switch to tab
  QTabWidget::setCurrentIndex(tab);

  // Select line and column
  if (0 < line) {
    QTextCursor c = editor->textCursor();

    c.setPosition(0, QTextCursor::MoveAnchor);
    c.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, line - 1);

    if (0 < col)
      c.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, col);

    c.select(QTextCursor::LineUnderCursor);

    editor->setTextCursor(c);
  }

  // Get input focus
  editor->setFocus();
}