Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
loggerWidget.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41 
42 /*===========================================================================*\
43 * *
44 * $Revision$ *
45 * $LastChangedBy$ *
46 * $Date$ *
47 * *
48 \*===========================================================================*/
49 
50 
51 
52 
53 #include "loggerWidget.hh"
54 
56 
58 
59 LoggerWidget::LoggerWidget( QWidget *parent)
60  : QWidget(parent),
61  newData_(true)
62 {
63  // Don't delete this widget on close actions
64  // since it may be embedded in different widget
65  // containers at the same time
66  setAttribute(Qt::WA_DeleteOnClose, false);
67 
68  QVBoxLayout* vlayout = new QVBoxLayout();
69  QHBoxLayout* hlayout = new QHBoxLayout();
70 
71  list_ = new QListWidget();
72 
73  list_->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
74  list_->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
75  list_->setFocusPolicy(Qt::NoFocus);
76  list_->setSelectionMode(QAbstractItemView::ExtendedSelection);
77  list_->setUniformItemSizes(true);
78 
79  QString path = OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator();
80 
81  // ============================
82  // Context Menu
83  // ============================
84  context_ = new QMenu(tr("Log Viewer"));
85 
86  QAction* copyAction = new QAction(QIcon(path + "edit-copy.png"), tr("Copy"),0);
87  copyAction->setShortcut( QKeySequence("Ctrl+C") );
88  QAction* selectAction = new QAction(tr("Select All"),0);
89  selectAction->setShortcut( QKeySequence("Ctrl+A") );
90 
91  connect (copyAction, SIGNAL(triggered()), this, SLOT(copySelected()));
92  connect (selectAction, SIGNAL(triggered()), list_, SLOT(selectAll()));
93 
94  context_->addAction(copyAction);
95  context_->addSeparator();
96  context_->addAction(selectAction);
97 
98 
99  // ============================
100  // Filters Menu
101  // ============================
102  filterMenu_ = new QMenu(tr("Log Viewer"));
103 
104  openMeshFilterAction_ = new QAction(QIcon(path + "edit-copy.png"), tr("Enable OpenMesh error messages"),0);
105  openMeshFilterAction_->setCheckable(true);
106 
107 
108  if ( OpenFlipperSettings().value("Core/Gui/LogWindow/OpenMeshErrors",true).toBool() ) {
109  openMeshFilterAction_->setChecked( true );
110  omerr().enable();
111  } else {
112  openMeshFilterAction_->setChecked( false );
113  omerr().disable();
114  }
115 
116  filterMenu_->addAction(openMeshFilterAction_);
117 
118  // ============================
119  // Scrollbar
120  // ============================
121  blockNext_ = false;
122 
123  connect (&loggerUpdateTimer_, SIGNAL(timeout ()), this, SLOT(slotScrollUpdate()));
124 
125  // Single shot timer every 500 msecs
126  loggerUpdateTimer_.setSingleShot(true);
127  loggerUpdateTimer_.setInterval(500);
128 
129  allButton_ = new QPushButton(QIcon(path + "status_all.png"),tr("All Messages"));
130  allButton_->setCheckable(true);
131  allButton_->setAutoExclusive(true);
132  infoButton_ = new QPushButton(QIcon(path + "status_green.png"),tr("Informations"));
133  infoButton_->setCheckable(true);
134  infoButton_->setAutoExclusive(true);
135  warnButton_ = new QPushButton(QIcon(path + "status_yellow.png"),tr("Warnings"));
136  warnButton_->setCheckable(true);
137  warnButton_->setAutoExclusive(true);
138  errorButton_ = new QPushButton(QIcon(path + "status_red.png"),tr("Errors"));
139  errorButton_->setCheckable(true);
140  errorButton_->setAutoExclusive(true);
141 
142  filterButton_ = new QPushButton(QIcon(path + "status_filter.png"),tr("Set Filters"));
143  filterButton_->setCheckable(false);
144 
145  allButton_->setChecked(true);
146 
147  connect(allButton_, SIGNAL(clicked()), this, SLOT(updateList()));
148  connect(infoButton_, SIGNAL(clicked()), this, SLOT(updateList()));
149  connect(warnButton_, SIGNAL(clicked()), this, SLOT(updateList()));
150  connect(errorButton_, SIGNAL(clicked()), this, SLOT(updateList()));
151  connect(filterButton_,SIGNAL(clicked()), this, SLOT(slotFilterMenu()));
152 
153  clearButton_ = new QPushButton(QIcon(path + "edit-clear.png"),tr("Clear Messages"));
154  connect(clearButton_, SIGNAL(clicked()), list_, SLOT(clear()));
155 
156  hlayout->addWidget( allButton_ );
157  hlayout->addWidget( infoButton_ );
158  hlayout->addWidget( warnButton_ );
159  hlayout->addWidget( errorButton_ );
160  hlayout->addStretch();
161  hlayout->addWidget( filterButton_ );
162  hlayout->addStretch();
163  hlayout->addWidget( clearButton_ );
164 
165  hlayout->setSpacing(0);
166  hlayout->setContentsMargins (0,0,0,0);
167  vlayout->setSpacing(0);
168  vlayout->setContentsMargins (0,0,0,0);
169 
170  vlayout->addWidget(list_);
171  vlayout->addLayout( hlayout );
172 
173  setLayout( vlayout );
174 }
175 
176 LoggerWidget::~LoggerWidget()
177 {
178  delete clearButton_;
179  delete errorButton_;
180  delete warnButton_;
181  delete infoButton_;
182  delete allButton_;
183  delete context_;
184  delete list_;
185 }
186 
187 
188 //-------------------------------------------------------------------------------------
189 
191 void LoggerWidget::append(const QString& _text, Logtype _type){
192 
193  list_->addItem(_text);
194 
195  QListWidgetItem* item = list_->item( list_->count()-1 );
196 
197  if ( allButton_->isChecked() )
198  item->setHidden(false);
199  else
200  item->setHidden(true);
201 
202  switch (_type) {
203  case LOGINFO:
204  item->setForeground( QBrush(QColor(Qt::darkGreen)) );
205  item->setBackground( QBrush(QColor(225,255,225), Qt::Dense4Pattern) );
206 
207  if ( infoButton_->isChecked() )
208  item->setHidden(false);
209  break;
210  case LOGOUT:
211  item->setForeground( QBrush(QColor(Qt::black)) );
212  break;
213  case LOGWARN:
214  item->setForeground( QBrush(QColor(160,160,0)) );
215  item->setBackground( QBrush(QColor(255,240,200),Qt::Dense4Pattern) );
216 
217  if ( warnButton_->isChecked() )
218  item->setHidden(false);
219  break;
220  case LOGERR:
221  item->setForeground( QBrush(QColor(Qt::red)) );
222  item->setBackground( QBrush(QColor(255,225,225),Qt::Dense4Pattern) );
223 
224  if ( errorButton_->isChecked() )
225  item->setHidden(false);
226  break;
227  case LOGSTATUS:
228  item->setForeground( QBrush(QColor(Qt::blue)) );
229  item->setBackground( QBrush(QColor(255,225,225),Qt::Dense4Pattern) );
230 
231  if ( errorButton_->isChecked() )
232  item->setHidden(false);
233  break;
234  }
235 
236  // If the logger is hidden, we just ignore the update ... done by showEvent later
237  if ( isHidden() )
238  return;
239 
240  // Remember that we have new logs to show
241  newData_ = true;
242 
243  // Check if we already have a running timer.
244  // If so, the timeout of that timer will trigger the redraw.
245  // Otherwise, we redraw and start the timer to block concurrent redraws.
246  // Only if new data is available, the redraw at the timers timeout will be done.
247  if ( ! loggerUpdateTimer_.isActive() ) {
248  // Update the logger
249  list_->scrollToBottom();
250 
251  // Remember that there is no new data now.
252  // This might change again on a call to this function, while the timer is active.
253  newData_ = false;
254 
255  // start the timer
256  loggerUpdateTimer_.start();
257  }
258 
259 }
260 
261 //-------------------------------------------------------------------------------------
262 
264 
265  // If there is data to show, do it.
266  if ( newData_ ) {
267  list_->scrollToBottom();
268  newData_ = false;
269  }
270 
271 }
272 
273 //-------------------------------------------------------------------------------------
274 
277 
278  QColor color;
279 
280  if ( infoButton_->isChecked() )
281  color = QColor(Qt::darkGreen);
282  else if ( warnButton_->isChecked() )
283  color = QColor(160,160,0);
284  else if ( errorButton_->isChecked() )
285  color = QColor(Qt::red);
286  else
287  color = QColor(Qt::black);
288 
289  if (color == QColor(Qt::black)){
290 
291  for (int i=0; i < list_->count(); i++)
292  list_->item( i )->setHidden(false);
293 
294  } else {
295 
296  for (int i=0; i < list_->count(); i++)
297  if ( list_->item(i)->foreground().color() == color )
298  list_->item( i )->setHidden(false);
299  else
300  list_->item( i )->setHidden(true);
301  }
302 
303  list_->scrollToBottom();
304 }
305 
306 //-------------------------------------------------------------------------------------
307 void LoggerWidget::showEvent ( QShowEvent * /*event*/ ) {
308  list_->scrollToBottom();
309 }
310 
311 //-------------------------------------------------------------------------------------
312 
314 void LoggerWidget::keyPressEvent (QKeyEvent * _event ) {
315  // Return key event to parent if not one of the standard key combinations ( ... Core )
316  if ( (_event->modifiers() & Qt::ControlModifier ) && ( _event->key() == Qt::Key_C ) )
317  copySelected();
318 
319  else if ( (_event->modifiers() & Qt::ControlModifier ) && ( _event->key() == Qt::Key_A ) )
320  list_->selectAll();
321 
322  else
323  _event->ignore();
324 }
325 
326 //-------------------------------------------------------------------------------------
327 
329 void LoggerWidget::contextMenuEvent ( QContextMenuEvent * event ){
330 
331  QPoint p = list_->mapToGlobal( event->pos() );
332 
333  context_->popup( p );
334 
335 }
336 
337 //-------------------------------------------------------------------------------------
338 
341 
342  QString str = "";
343 
344  for (int i=0; i < list_->selectedItems().count(); i++)
345  str += (list_->selectedItems()[i])->text() + "\n";
346 
347  QClipboard *clipboard = QApplication::clipboard();
348 
349  clipboard->setText(str);
350 }
351 
352 //-------------------------------------------------------------------------------------
353 
355  filterMenu_->popup( list_->mapToGlobal(filterButton_->pos()) );
356 }
357 
void copySelected()
copy Selected rows to clipboard
void showEvent(QShowEvent *event)
Called when the widget is shown.
void append(const QString &_text, Logtype _type)
Append a new logmessage to log viewer.
void updateList()
update the list if a button was pressed
void keyPressEvent(QKeyEvent *_event)
Grab key events.
void slotScrollUpdate()
Called when we want to scroll to the bottom.
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
void contextMenuEvent(QContextMenuEvent *event)
Show context menu.
Logtype
Log types for Message Window.
void slotFilterMenu()
Called when filter button is pressed.