37 #include <QVBoxLayout>
40 #include <QContextMenuEvent>
53 #include <QTableWidget>
55 #include <QHeaderView>
56 #include <QStackedLayout>
57 #include <QApplication>
60 #include <QPushButton>
100 if (event->key() == Qt::Key_C && (
event->modifiers() & Qt::ControlModifier))
102 QModelIndexList cells = selectedIndexes();
107 foreach (
const QModelIndex& cell, cells) {
108 if (text.length() == 0) {
110 }
else if (cell.row() != currentRow) {
117 currentRow = cell.row();
118 text += cell.data().toString();
121 QApplication::clipboard()->setText(text);
128 QTableWidget::keyPressEvent(event);
136 mScrollToBottomEnabled(true)
139 QVBoxLayout* layout =
new QVBoxLayout(
this);
140 layout->setMargin(0);
141 this->setLayout(layout);
142 layout->addWidget(
mTable);
144 mTable->setShowGrid(
false);
145 mTable->setTextElideMode(Qt::ElideLeft);
146 mTable->setWordWrap(
false);
148 mTable->setColumnCount(6);
150 mTable->setHorizontalHeaderLabels(QStringList() <<
"time" <<
"source" <<
"function" <<
"thread" <<
"level" <<
"description");
151 mTable->setSelectionBehavior(QAbstractItemView::SelectRows);
152 mTable->verticalHeader()->hide();
154 QFontMetrics metric(this->font());
155 mTable->setColumnWidth(0, metric.width(
"00:00:00.000xx"));
156 mTable->setColumnWidth(1, metric.width(
"cxSourceFile.cpp:333xx"));
157 mTable->setColumnWidth(2, metric.width(
"function()xx"));
158 mTable->setColumnWidth(3, metric.width(
"mainxx"));
159 mTable->setColumnWidth(4, metric.width(
"WARNINGxx"));
160 mTable->horizontalHeader()->setStretchLastSection(
true);
162 for (
int i=0; i<
mTable->horizontalHeader()->count(); ++i)
165 int value = headerItem.
readValue(
"-1").toInt();
168 mTable->setColumnWidth(i, value);
171 int textLineHeight = metric.lineSpacing();
172 mTable->verticalHeader()->setDefaultSectionSize(textLineHeight);
177 for (
int i=0; i<
mTable->horizontalHeader()->count(); ++i)
191 mTable->horizontalScrollBar()->setValue(
mTable->horizontalScrollBar()->minimum());
196 int row =
mTable->rowCount();
199 QTableWidgetItem* item = NULL;
201 QString timestamp = message.
getTimeStamp().toString(
"hh:mm:ss.zzz");
202 item = this->
addItem(0, timestamp, message);
207 item = this->
addItem(1, source, message);
211 item = this->
addItem(2,
function, message);
213 QString thread = message.
mThread;
214 item = this->
addItem(3, thread, message);
217 item = this->
addItem(4, level, message);
219 QString desc = message.
getText();
220 item = this->
addItem(5, desc, message);
233 mTable->horizontalHeader()->setVisible(on);
244 int row =
mTable->rowCount();
246 QTableWidgetItem* item =
new QTableWidgetItem(text);
247 item->setStatusTip(text);
248 item->setToolTip(text);
250 item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
251 mTable->setItem(row-1, column, item);
261 mScrollToBottomEnabled(true)
265 mBrowser->setLineWrapMode(QTextEdit::NoWrap);
266 QVBoxLayout* layout =
new QVBoxLayout(
this);
267 layout->setMargin(0);
268 this->setLayout(layout);
270 this->scrollToBottom();
276 this->scrollToBottom();
281 mBrowser->horizontalScrollBar()->setValue(
mBrowser->horizontalScrollBar()->minimum());
290 this->scrollToBottom();
295 mScrollToBottomEnabled = on;
296 this->scrollToBottom();
299 void SimpleLogMessageDisplayWidget::scrollToBottom()
301 if (mScrollToBottomEnabled)
302 mBrowser->verticalScrollBar()->setValue(
mBrowser->verticalScrollBar()->maximum());
308 return message.
mText;
311 retval= QString(
"[%1] %2")
351 QVBoxLayout* layout =
new QVBoxLayout(
this);
352 layout->setMargin(0);
353 this->setLayout(layout);
357 mShowHeaderButton = expandButton;
358 this->setFixedSize(expandButton->sizeHint());
360 QAction* action =
new QAction(QIcon(
":icons/open_icon_library/layer-lower-3.png"),
"Controls",
this);
361 QString tip =
"Show Controls";
362 action->setStatusTip(tip);
363 action->setWhatsThis(tip);
364 action->setToolTip(tip);
365 connect(action, SIGNAL(triggered()),
this, SLOT(onTriggered()));
368 mShowHeaderButton->setDefaultAction(action);
369 layout->addWidget(mShowHeaderButton);
371 action->setCheckable(
true);
381 return mShowHeaderButton->isChecked();
384 void PopupButton::onTriggered()
387 mAction->setIcon(QIcon(
":icons/open_icon_library/layer-raise-3.png"));
389 mAction->setIcon(QIcon(
":icons/open_icon_library/layer-lower-3.png"));
401 mSeverityAction(NULL),
402 mMessagesWidget(NULL),
403 mMessagesLayout(NULL),
415 mSeverityAction(NULL),
416 mMessagesWidget(NULL),
417 mMessagesLayout(NULL),
420 mOptions =
profile()->getXmlSettings().descend(this->objectName());
429 if (!mMessagesLayout)
436 void ConsoleWidget::createUI()
438 mSeverityAction = NULL;
439 mMessagesWidget = NULL;
443 QVBoxLayout* layout =
new QVBoxLayout;
444 layout->setMargin(0);
445 layout->setSpacing(0);
446 this->setLayout(layout);
448 mControlLayout =
new QHBoxLayout;
449 mControlLayout->setMargin(0);
450 layout->addLayout(mControlLayout);
453 mControlLayout->addWidget(mShowControlsButton);
454 connect(mShowControlsButton, &
PopupButton::popup,
this, &ConsoleWidget::updateShowHeader);
456 this->createButtonWidget();
458 mControlLayout->addStretch(1);
460 mMessagesLayout =
new QVBoxLayout;
461 mMessagesLayout->setMargin(0);
462 layout->addLayout(mMessagesLayout);
466 mMessageListener->installFilter(mMessageFilter);
470 QString defVal = enum2string<LOG_SEVERITY>(
msINFO);
471 LOG_SEVERITY value = string2enum<LOG_SEVERITY>(this->option(
"showLevel").
readValue(defVal));
472 mMessageFilter->setLowestSeverity(value);
474 mMessageFilter->setActiveChannel(mChannelSelector->getValue());
475 mMessageListener->installFilter(mMessageFilter);
480 void ConsoleWidget::createButtonWidget()
482 mButtonWidget =
new QWidget(
this);
483 mControlLayout->addWidget(mButtonWidget);
485 QHBoxLayout* buttonLayout =
new QHBoxLayout;
486 buttonLayout->setMargin(0);
487 buttonLayout->setSpacing(0);
489 mButtonWidget->setLayout(buttonLayout);
491 this->addSeverityButtons(buttonLayout);
492 buttonLayout->addSpacing(8);
493 this->addDetailsButton(buttonLayout);
495 this->createChannelSelector();
497 LabeledComboBoxWidget* channelSelectorWidget =
new LabeledComboBoxWidget(
this, mChannelSelector);
498 channelSelectorWidget->showLabel(
false);
499 buttonLayout->addSpacing(8);
500 buttonLayout->addWidget(channelSelectorWidget);
501 buttonLayout->setStretch(buttonLayout->count()-1, 0);
503 buttonLayout->addStretch(1);
506 void ConsoleWidget::updateShowHeader()
511 mButtonWidget->setVisible(show);
515 mControlLayout->insertWidget(0, mShowControlsButton);
520 mControlLayout->removeWidget(mShowControlsButton);
521 mShowControlsButton->setParent(NULL);
522 mShowControlsButton->setParent(
this);
523 mShowControlsButton->setVisible(
true);
529 XmlOptionItem ConsoleWidget::option(QString name)
531 return XmlOptionItem(name, mOptions.
getElement());
539 QString levelString = enum2string<LOG_SEVERITY>(mMessageFilter->getLowestSeverity());
540 this->option(
"showLevel").
writeValue(levelString);
541 this->option(
"showDetails").
writeVariant(mDetailsAction->isChecked());
547 "<h3>CustusX console.</h3>"
548 "<p>Display device for system administration messages.</p>"
549 "<p><i>Right click for addition options.</i></p>"
557 mDetailsAction->setChecked(on);
566 void ConsoleWidget::addSeverityButtons(QBoxLayout* buttonLayout)
569 QIcon(
":/icons/open_icon_library/zoom-in-3.png"),
570 "More",
"More detailed log output",
571 SLOT(onSeverityDown()),
574 this->addSeverityIndicator(buttonLayout);
577 QIcon(
":/icons/open_icon_library/zoom-out-3.png"),
578 "Less ",
"Less detailed log output",
579 SLOT(onSeverityUp()),
583 void ConsoleWidget::addSeverityIndicator(QBoxLayout* buttonLayout)
585 QAction* action =
new QAction(QIcon(
""),
"Severity",
this);
586 mSeverityAction = action;
587 QString help =
"Lowest displayed log severity";
588 action->setStatusTip(help);
589 action->setWhatsThis(help);
590 action->setToolTip(help);
592 button->setDefaultAction(action);
593 buttonLayout->addWidget(button);
596 void ConsoleWidget::updateSeverityIndicator()
598 LOG_SEVERITY severity = mMessageFilter->getLowestSeverity();
603 this->updateSeverityIndicator(
"window-close-3.png",
"error");
606 this->updateSeverityIndicator(
"dialog-warning-panel.png",
"warning");
609 this->updateSeverityIndicator(
"dialog-information-4.png",
"info");
612 this->updateSeverityIndicator(
"script-error.png",
"debug");
615 this->updateSeverityIndicator(
"script-error.png",
"");
620 void ConsoleWidget::updateSeverityIndicator(QString iconname, QString help)
622 QIcon icon(QString(
":/icons/message_levels/%1").arg(iconname));
623 mSeverityAction->setIcon(icon);
625 help = QString(
"Current log level is %1").arg(help);
626 mSeverityAction->setStatusTip(help);
627 mSeverityAction->setToolTip(help);
630 void ConsoleWidget::onSeverityUp()
632 this->onSeverityChange(-1);
635 void ConsoleWidget::onSeverityDown()
637 this->onSeverityChange(+1);
640 void ConsoleWidget::onSeverityChange(
int delta)
642 LOG_SEVERITY severity = mMessageFilter->getLowestSeverity();
643 int val = (int)severity + delta;
645 severity =
static_cast<LOG_SEVERITY
>(val);
647 mMessageFilter->setLowestSeverity(severity);
648 mMessageListener->installFilter(mMessageFilter);
652 void ConsoleWidget::createChannelSelector()
654 QString defval =
"console";
660 "",
"Log Channel to display",
663 mChannelSelector = retval;
666 void ConsoleWidget::addDetailsButton(QBoxLayout* buttonLayout)
668 QIcon icon(
":/icons/open_icon_library/system-run-5.png");
671 "Details",
"Show detailed info on each log entry",
674 action->setCheckable(
true);
676 bool value = this->option(
"showDetails").
readVariant(
false).toBool();
677 action->blockSignals(
true);
678 action->setChecked(value);
679 action->blockSignals(
false);
681 mDetailsAction = action;
684 void ConsoleWidget::updateUI()
686 this->updateSeverityIndicator();
688 this->setWindowTitle(
"Console: " + mChannelSelector->getValue());
689 this->selectMessagesWidget();
690 this->updateShowHeader();
693 QTimer::singleShot(0,
this, SLOT(clearTable()));
695 mMessageListener->restart();
698 void ConsoleWidget::selectMessagesWidget()
700 if (mMessagesWidget && (mMessagesWidget->
getType()==this->getDetailTypeFromButton()))
706 mMessagesLayout->takeAt(0);
707 delete mMessagesWidget;
710 if (this->getDetailTypeFromButton()==
"detail")
712 mMessagesWidget =
new DetailedLogMessageDisplayWidget(
this, mOptions);
716 mMessagesWidget =
new SimpleLogMessageDisplayWidget(
this);
719 mMessagesLayout->addWidget(mMessagesWidget);
722 QString ConsoleWidget::getDetailTypeFromButton()
const
724 if (mDetailsAction->isChecked())
730 void ConsoleWidget::clearTable()
733 mMessagesWidget->
clear();
736 void ConsoleWidget::onLoggingFolderChanged()
740 mMessageListener->installFilter(mMessageFilter);
744 void ConsoleWidget::onChannelSelectorChanged()
746 mChannelSelector->blockSignals(
true);
748 mMessageFilter->setActiveChannel(mChannelSelector->getValue());
749 mMessageListener->installFilter(mMessageFilter);
752 mChannelSelector->blockSignals(
false);
770 void ConsoleWidget::receivedChannel(QString channel)
772 if (!mChannels.count(channel))
774 mChannels.append(channel);
775 mChannelSelector->setValueRange(mChannels);
779 void ConsoleWidget::receivedMessage(
Message message)
781 this->receivedChannel(message.
mChannel);
788 this->printMessage(message);
791 void ConsoleWidget::printMessage(
const Message& message)
794 mMessagesWidget->
add(message);
static MessageListenerPtr create(LogPtr log=LogPtr())
cxResource_EXPORT ProfilePtr profile()
void newChannel(QString channel)
void writeVariant(const QVariant &val)
void loggingFolderChanged()
QString getText() const
The raw message.
QDomElement getElement()
return the current element
QDateTime getTimeStamp() const
The time at which the message was created.
MESSAGE_LEVEL mMessageLevel
Helper class for storing one string value in an xml document.
boost::shared_ptr< class StringProperty > StringPropertyPtr
boost::shared_ptr< class Log > LogPtr
double constrainValue(double val, double min, double max)
void changed()
emit when the underlying data value is changed: The user interface will be updated.
static StringPropertyPtr initialize(const QString &uid, QString name, QString help, QString value, QStringList range, QDomNode root=QDomNode())
void writeValue(const QString &val)
QVariant readVariant(const QVariant &defval=QVariant()) const
void newMessage(Message message)
MESSAGE_LEVEL getMessageLevel() const
The category of the message.
QString enum2string(const ENUM &val)
Helper class for xml files used to store ssc/cx data.
QString readValue(const QString &defval) const