| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #include "ui/log_widget.h" |
| |
|
| | namespace colmap { |
| |
|
| | LogWidget::LogWidget(QWidget* parent, const int max_num_blocks) { |
| | setWindowFlags(Qt::Window); |
| | setWindowTitle("Log"); |
| | resize(320, parent->height()); |
| |
|
| | QGridLayout* grid = new QGridLayout(this); |
| | grid->setContentsMargins(5, 10, 5, 5); |
| |
|
| | qRegisterMetaType<QTextCursor>("QTextCursor"); |
| | qRegisterMetaType<QTextBlock>("QTextBlock"); |
| |
|
| | QTimer* timer = new QTimer(this); |
| | connect(timer, &QTimer::timeout, this, &LogWidget::Flush); |
| | timer->start(100); |
| |
|
| | |
| | |
| | cout_redirector_ = new StandardOutputRedirector<char, std::char_traits<char>>( |
| | std::cout, LogWidget::Update, this); |
| | cerr_redirector_ = new StandardOutputRedirector<char, std::char_traits<char>>( |
| | std::cerr, LogWidget::Update, this); |
| | clog_redirector_ = new StandardOutputRedirector<char, std::char_traits<char>>( |
| | std::clog, LogWidget::Update, this); |
| |
|
| | QHBoxLayout* left_button_layout = new QHBoxLayout(); |
| |
|
| | QPushButton* save_log_button = new QPushButton(tr("Save"), this); |
| | connect(save_log_button, &QPushButton::released, this, &LogWidget::SaveLog); |
| | left_button_layout->addWidget(save_log_button); |
| |
|
| | QPushButton* clear_button = new QPushButton(tr("Clear"), this); |
| | connect(clear_button, &QPushButton::released, this, &LogWidget::Clear); |
| | left_button_layout->addWidget(clear_button); |
| |
|
| | grid->addLayout(left_button_layout, 0, 0, Qt::AlignLeft); |
| |
|
| | QHBoxLayout* right_button_layout = new QHBoxLayout(); |
| |
|
| | grid->addLayout(right_button_layout, 0, 1, Qt::AlignRight); |
| |
|
| | text_box_ = new QPlainTextEdit(this); |
| | text_box_->setReadOnly(true); |
| | text_box_->setMaximumBlockCount(max_num_blocks); |
| | text_box_->setWordWrapMode(QTextOption::NoWrap); |
| | text_box_->setFont(QFont("Courier", 10)); |
| | grid->addWidget(text_box_, 1, 0, 1, 2); |
| | } |
| |
|
| | LogWidget::~LogWidget() { |
| | if (log_file_.is_open()) { |
| | log_file_.close(); |
| | } |
| |
|
| | delete cout_redirector_; |
| | delete cerr_redirector_; |
| | delete clog_redirector_; |
| | } |
| |
|
| | void LogWidget::Append(const std::string& text) { |
| | QMutexLocker locker(&mutex_); |
| | text_queue_ += text; |
| |
|
| | |
| | if (log_file_.is_open()) { |
| | log_file_ << text; |
| | } |
| | } |
| |
|
| | void LogWidget::Flush() { |
| | QMutexLocker locker(&mutex_); |
| |
|
| | if (text_queue_.size() > 0) { |
| | |
| | text_box_->moveCursor(QTextCursor::End); |
| | text_box_->insertPlainText(QString::fromStdString(text_queue_)); |
| | text_box_->moveCursor(QTextCursor::End); |
| | text_queue_.clear(); |
| | } |
| | } |
| |
|
| | void LogWidget::Clear() { |
| | QMutexLocker locker(&mutex_); |
| | text_queue_.clear(); |
| | text_box_->clear(); |
| | } |
| |
|
| | void LogWidget::Update(const char* text, std::streamsize count, |
| | void* log_widget_ptr) { |
| | std::string text_str; |
| | for (std::streamsize i = 0; i < count; ++i) { |
| | if (text[i] == '\n') { |
| | text_str += "\n"; |
| | } else { |
| | text_str += text[i]; |
| | } |
| | } |
| |
|
| | LogWidget* log_widget = static_cast<LogWidget*>(log_widget_ptr); |
| | log_widget->Append(text_str); |
| | } |
| |
|
| | void LogWidget::SaveLog() { |
| | const std::string log_path = |
| | QFileDialog::getSaveFileName(this, tr("Select path to log file"), "", |
| | tr("Log (*.log)")) |
| | .toUtf8() |
| | .constData(); |
| |
|
| | if (log_path == "") { |
| | return; |
| | } |
| |
|
| | std::ofstream file(log_path, std::ios::app); |
| | CHECK(file.is_open()) << log_path; |
| | file << text_box_->toPlainText().toUtf8().constData(); |
| | } |
| |
|
| | } |
| |
|