oopapidocs
2.0
|
00001 /**************************************************************************** 00002 This file is part of ChainLink 00003 Copyright (C) 2007 Jeremy Magland (Jeremy.Magland@gmail.com) 00004 00005 ChainLink is free software; you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published by 00007 the Free Software Foundation; either version 2 of the License, or 00008 (at your option) any later version. 00009 00010 ChainLink is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with ChainLink; if not, write to the Free Software 00017 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00018 00019 *****************************************************************************/ 00020 00021 #include "qobjectbrowser.h" 00022 #include "ui_qobjectbrowser.h" 00023 #include <QVBoxLayout> 00024 #include <QHeaderView> 00025 #include <QToolBar> 00026 #include <QSettings> 00027 #include <QTimer> 00028 #include <stdio.h> 00029 00030 00031 QObjectBrowserControl::QObjectBrowserControl(QWidget *parent) : QWidget(parent), 00032 ui (new Ui_qobjectbrowser){ 00033 ui->setupUi(this); 00034 00035 m_obj=0; 00036 00037 connect(ui->update_children_button,SIGNAL(clicked()),this,SLOT(on_update_children())); 00038 connect(ui->update_properties_button,SIGNAL(clicked()),this,SLOT(on_update_properties())); 00039 connect(ui->parent_button,SIGNAL(clicked()),this,SLOT(on_up_to_parent())); 00040 00041 connect(ui->children_table,SIGNAL(cellDoubleClicked (int,int)),this,SLOT(on_children_table_cell_clicked(int,int))); 00042 00043 set_object(parent); 00044 } 00045 QObjectBrowserControl::~QObjectBrowserControl() { 00046 delete ui; 00047 clear_signal_records(); 00048 } 00049 void QObjectBrowserControl::clear() { 00050 ui->children_table->clearContents(); ui->children_table->setRowCount(1); 00051 ui->properties_table->clearContents(); ui->properties_table->setRowCount(1); 00052 ui->signals_table->clearContents(); ui->signals_table->setRowCount(1); 00053 ui->slots_table->clearContents(); ui->slots_table->setRowCount(1); 00054 ui->methods_table->clearContents(); ui->methods_table->setRowCount(1); 00055 00056 ui->class_name->setText(""); 00057 ui->base_class_name->setText(""); 00058 00059 clear_signal_records(); 00060 00061 repaint(); 00062 00063 } 00064 00065 void QObjectBrowserControl::clear_signal_records() { 00066 int j; 00067 for (j=0; j<m_signal_records.count(); j++) 00068 delete m_signal_records[j]; 00069 m_signal_records.clear(); 00070 } 00071 bool QObjectBrowserControl::hasdescendent(QObject *obj) { 00072 while (obj) { 00073 if (obj==this) return true; 00074 obj=obj->parent(); 00075 } 00076 return false; 00077 } 00078 void QObjectBrowserControl::on_object_destroyed() { 00079 m_obj=0; 00080 clear(); 00081 } 00082 void QObjectBrowserControl::set_object(QObject *obj_in) { 00083 if (m_obj) { 00084 disconnect(m_obj,SIGNAL(destroyed()),this,SLOT(on_object_destroyed())); 00085 } 00086 m_obj=obj_in; 00087 00088 clear(); 00089 00090 if (!m_obj) return; 00091 00092 connect(m_obj,SIGNAL(destroyed()),this,SLOT(on_object_destroyed())); 00093 00094 const QMetaObject *metaobj=m_obj->metaObject(); 00095 if (!metaobj) return; 00096 ui->class_name->setText(metaobj->className()); 00097 if (metaobj->superClass()) 00098 ui->base_class_name->setText(metaobj->superClass()->className()); 00099 else 00100 ui->base_class_name->setText(""); 00101 00102 if (m_obj->parent()) 00103 ui->parent_button->setEnabled(true); 00104 else 00105 ui->parent_button->setEnabled(false); 00106 if ((m_obj->parent())&&(m_obj->parent()->metaObject())) 00107 ui->parent_class_name->setText(m_obj->parent()->metaObject()->className()); 00108 else 00109 ui->parent_class_name->setText(""); 00110 00111 set_children(); 00112 set_properties(); 00113 set_signals(); 00114 set_slots(); 00115 set_methods(); 00116 00117 emit object_changed(m_obj); 00118 } 00119 void QObjectBrowserControl::set_children() { 00120 ui->children_table->clear(); 00121 ui->children_table->horizontalHeader()->setResizeMode(QHeaderView::Stretch); 00122 ui->children_table->setColumnCount(2); 00123 ui->children_table->setHorizontalHeaderLabels(QStringList() << tr("Type") << tr("Name") ); 00124 00125 if (!m_obj) return; 00126 00127 QObjectList objlist=m_obj->children(); 00128 00129 ui->children_table->setRowCount(objlist.count()); 00130 00131 int j; 00132 QTableWidgetItem *item; 00133 for (j=0; j<objlist.count(); j++) { 00134 QString txt="[ ]"; 00135 const QMetaObject *metaobj=objlist[j]->metaObject(); 00136 if (metaobj) { 00137 txt=metaobj->className(); 00138 } 00139 00140 item=new QTableWidgetItem; 00141 item->setText(txt); 00142 item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled); 00143 ui->children_table->setItem(j,0,item); 00144 00145 item=new QTableWidgetItem; 00146 item->setText(objlist[j]->objectName()); 00147 item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled); 00148 ui->children_table->setItem(j,1,item); 00149 00150 } 00151 } 00152 void QObjectBrowserControl::set_properties() { 00153 ui->properties_table->clear(); 00154 ui->properties_table->horizontalHeader()->setResizeMode(QHeaderView::Stretch); 00155 ui->properties_table->setColumnCount(3); 00156 ui->properties_table->setHorizontalHeaderLabels(QStringList() << tr("Type") << tr("Name") << tr("Value")); 00157 00158 if (!m_obj) return; 00159 const QMetaObject *metaobj=m_obj->metaObject(); 00160 if (!metaobj) return; 00161 00162 00163 ui->properties_table->setRowCount(metaobj->propertyCount()); 00164 00165 int j; 00166 QTableWidgetItem *item; 00167 for (j=0; j<metaobj->propertyCount(); j++) { 00168 QMetaProperty prop=metaobj->property(j); 00169 00170 item=new QTableWidgetItem; 00171 item->setText(prop.typeName()); 00172 item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled); 00173 ui->properties_table->setItem(j,0,item); 00174 00175 item=new QTableWidgetItem; 00176 item->setText(prop.name()); 00177 item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled); 00178 ui->properties_table->setItem(j,1,item); 00179 00180 item=new QTableWidgetItem; 00181 item->setText(prop.read(m_obj).toString()); 00182 item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled); 00183 ui->properties_table->setItem(j,2,item); 00184 } 00185 } 00186 void QObjectBrowserControl::set_signals() { 00187 ui->signals_table->clear(); 00188 clear_signal_records(); 00189 ui->signals_table->horizontalHeader()->setResizeMode(QHeaderView::Stretch); 00190 ui->signals_table->setColumnCount(2); 00191 ui->signals_table->setHorizontalHeaderLabels(QStringList() << tr("Signal") << tr("Count")); // << tr("Connects")); 00192 00193 if (m_obj==(QObject *)ui->signals_table) { 00194 //don't map the signals for the signal table, due to recursion 00195 return; 00196 } 00197 00198 if (!m_obj) return; 00199 const QMetaObject *metaobj=m_obj->metaObject(); 00200 if (!metaobj) return; 00201 00202 int ct=0; 00203 int j; 00204 for (j=0; j<metaobj->methodCount(); j++) 00205 if (metaobj->method(j).methodType()==QMetaMethod::Signal) 00206 ct++; 00207 ui->signals_table->setRowCount(ct); 00208 00209 QTableWidgetItem *item; 00210 ct=0; 00211 00212 for (j=0; j<metaobj->methodCount(); j++) { 00213 QMetaMethod meth=metaobj->method(j); 00214 if (meth.methodType()==QMetaMethod::Signal) { 00215 QOB_signal_record *ptr=new QOB_signal_record; 00216 ptr->m_sigmapper=new QSignalMapper; 00217 ptr->m_sigmapper->setMapping(m_obj,ct); 00218 char holdstr[1000]; 00219 sprintf(holdstr,"2%s",meth.signature()); 00220 connect(m_obj,holdstr,ptr->m_sigmapper,SLOT(map())); 00221 connect(ptr->m_sigmapper,SIGNAL(mapped(int)),this,SLOT(on_signal_triggered(int))); 00222 m_signal_records.append(ptr); 00223 00224 item=new QTableWidgetItem; 00225 item->setText(meth.signature()); 00226 item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled); 00227 ui->signals_table->setItem(ct,0,item); 00228 // TODO: setItem (ct, 2, new item that shows the number of connections ) 00229 00230 00231 ct++; 00232 } 00233 } 00234 update_signal_values(); 00235 } 00236 void QObjectBrowserControl::update_signal_values() { 00237 if (!m_obj) return; 00238 const QMetaObject *metaobj=m_obj->metaObject(); 00239 if (!metaobj) return; 00240 00241 int ct=0; 00242 int j; 00243 for (j=0; j<metaobj->methodCount(); j++) { 00244 QMetaMethod meth=metaobj->method(j); 00245 if (meth.methodType()==QMetaMethod::Signal) { 00246 update_signal_value(ct); 00247 ct++; 00248 } 00249 } 00250 00251 } 00252 void QObjectBrowserControl::update_signal_value(int sig_num) { 00253 QTableWidgetItem *item=new QTableWidgetItem; 00254 if ((sig_num>=0)&&(sig_num<m_signal_records.count())) { 00255 item->setText(QString::number(m_signal_records[sig_num]->m_count)); 00256 item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled); 00257 } 00258 ui->signals_table->setItem(sig_num,1,item); 00259 00260 00261 00262 } 00263 void QObjectBrowserControl::set_slots() { 00264 ui->slots_table->clear(); 00265 ui->slots_table->horizontalHeader()->setResizeMode(QHeaderView::Stretch); 00266 ui->slots_table->setColumnCount(2); 00267 ui->slots_table->setHorizontalHeaderLabels(QStringList() << "Type" << "Slot"); 00268 00269 if (!m_obj) return; 00270 const QMetaObject *metaobj=m_obj->metaObject(); 00271 if (!metaobj) return; 00272 00273 int ct=0; 00274 int j; 00275 for (j=0; j<metaobj->methodCount(); j++) 00276 if (metaobj->method(j).methodType()==QMetaMethod::Slot) 00277 ct++; 00278 ui->slots_table->setRowCount(ct); 00279 00280 ct=0; 00281 QTableWidgetItem *item; 00282 for (j=0; j<metaobj->methodCount(); j++) { 00283 QMetaMethod meth=metaobj->method(j); 00284 if (meth.methodType()==QMetaMethod::Slot) { 00285 item=new QTableWidgetItem; 00286 00287 QString typeName = meth.typeName(); 00288 if( typeName.isEmpty() ) 00289 typeName = "void"; 00290 00291 item->setText(typeName); 00292 item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled); 00293 ui->slots_table->setItem(ct,0,item); 00294 item=new QTableWidgetItem; 00295 item->setText(meth.signature()); 00296 item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled); 00297 ui->slots_table->setItem(ct,1,item); 00298 00299 ct++; 00300 } 00301 } 00302 } 00303 void QObjectBrowserControl::set_methods() { 00304 ui->methods_table->clear(); 00305 ui->methods_table->horizontalHeader()->setResizeMode(QHeaderView::Stretch); 00306 ui->methods_table->setColumnCount(2); 00307 ui->methods_table->setHorizontalHeaderLabels(QStringList() << "Type" << "Slot"); 00308 00309 if (!m_obj) return; 00310 const QMetaObject *metaobj=m_obj->metaObject(); 00311 if (!metaobj) return; 00312 00313 int ct=0; 00314 int j; 00315 for (j=0; j<metaobj->methodCount(); j++) 00316 if (metaobj->method(j).methodType()==QMetaMethod::Method) 00317 ct++; 00318 ui->methods_table->setRowCount(ct); 00319 00320 ct=0; 00321 QTableWidgetItem *item; 00322 for (j=0; j<metaobj->methodCount(); j++) { 00323 QMetaMethod meth=metaobj->method(j); 00324 if (meth.methodType()==QMetaMethod::Method) { 00325 item=new QTableWidgetItem; 00326 item->setText(meth.typeName()); 00327 item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled); 00328 ui->methods_table->setItem(ct,0,item); 00329 00330 item=new QTableWidgetItem; 00331 item->setText(meth.signature()); 00332 item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled); 00333 ui->methods_table->setItem(ct,1,item); 00334 00335 ct++; 00336 } 00337 } 00338 } 00339 00340 void QObjectBrowserControl::on_signal_triggered(int signal_num) { 00341 if ((signal_num<0)||(signal_num>=m_signal_records.count())) 00342 return; 00343 m_signal_records[signal_num]->m_count++; 00344 update_signal_value(signal_num); 00345 } 00346 void QObjectBrowserControl::on_update_children() { 00347 set_children(); 00348 } 00349 void QObjectBrowserControl::on_update_properties() { 00350 set_properties(); 00351 } 00352 void QObjectBrowserControl::on_up_to_parent() { 00353 if ((m_obj)&&(m_obj->parent())) 00354 set_object(m_obj->parent()); 00355 } 00356 00357 void QObjectBrowserControl::on_children_table_cell_clicked(int row, int column) { 00358 Q_UNUSED(column); 00359 if (!m_obj) return; 00360 QObjectList objlist=m_obj->children(); 00361 if (row<objlist.count()) { 00362 set_object(objlist[row]); 00363 } 00364 } 00365 00366 00367 QOB_signal_record::QOB_signal_record() { 00368 m_sigmapper=0; 00369 m_count=0; 00370 } 00371 QOB_signal_record::~QOB_signal_record() { 00372 if (m_sigmapper) delete m_sigmapper; 00373 m_sigmapper=0; 00374 } 00375 00376 QObjectBrowser::QObjectBrowser(QWidget* parent) : QWidget(parent), 00377 m_control (new QObjectBrowserControl), 00378 m_tree (new QObjectTree) { 00379 m_last_focus_window=0; 00380 setObjectName("QObjectBrowser"); 00381 setWindowTitle(tr("QObject Browser")); 00382 // setWindowFlags(windowFlags()|Qt::WindowStaysOnTopHint); 00383 // setWindowFlags(windowFlags()|Qt::WindowStaysOnTopHint|Qt::X11BypassWindowManagerHint); 00384 00385 m_tree->setModel(&m_model); 00386 QVBoxLayout *layout = new QVBoxLayout(this); 00387 setLayout(layout); 00388 QToolBar *update_toolbar=new QToolBar(tr("Update")); 00389 layout->addWidget(update_toolbar); 00390 00391 QSplitter *splitter=new QSplitter(Qt::Horizontal,this); 00392 layout->addWidget(splitter); 00393 splitter->addWidget(m_tree.data()); 00394 splitter->addWidget(m_control.data()); 00395 splitter->setStretchFactor(0,1); 00396 splitter->setStretchFactor(1,0); 00397 00398 m_tree->update(); 00399 00400 QPushButton *update_button=new QPushButton(QString("Update"),this); 00401 update_toolbar->addWidget(update_button); 00402 connect(update_button, SIGNAL(clicked()), this, SLOT(on_update())); 00403 00404 QPushButton *dump_button = new QPushButton(QString("DumpObject"), this); 00405 update_toolbar->addWidget(dump_button); 00406 connect(dump_button, SIGNAL(clicked()), this, SLOT(dumpObject())); 00407 00408 QPushButton *focus_button=new QPushButton(QString("Browse Focus Widget"),this); 00409 update_toolbar->addWidget(focus_button); 00410 connect(focus_button, SIGNAL(clicked()), this, SLOT(on_browse_focus())); 00411 00412 00413 connect(m_tree.data(),SIGNAL(show_widget()),this,SLOT(on_show_widget())); 00414 connect(m_tree.data(),SIGNAL(hide_widget()),this,SLOT(on_hide_widget())); 00415 connect(m_tree.data(),SIGNAL(focus_widget()),this,SLOT(on_focus_widget())); 00416 connect(m_tree.data(),SIGNAL(current_item_changed()),this,SLOT(on_current_item_changed())); 00417 connect(m_control.data(),SIGNAL(object_changed(QObject *)),this,SLOT(on_object_changed(QObject *))); 00418 connect(qApp,SIGNAL(focusChanged ( QWidget *, QWidget *)),this,SLOT(on_focus_changed( QWidget *, QWidget *))); 00419 00420 QTimer *timer = new QTimer(this); 00421 connect(timer, SIGNAL(timeout()), this, SLOT(on_update())); 00422 //connect(timer, SIGNAL(timeout()), this, SLOT(on_current_item_changed())); 00423 timer->start(3000); 00424 restoreSettings(); 00425 } 00426 00427 void QObjectBrowser::closeEvent(QCloseEvent * e) { 00428 saveSettings(); 00429 emit hidden(); 00430 QWidget::closeEvent(e); 00431 } 00432 00433 void QObjectBrowser::saveSettings() { 00434 QSettings s; 00435 s.setValue("obrowser/geometry", geometry()); 00436 } 00437 00438 void QObjectBrowser::restoreSettings() { 00439 QSettings s; 00440 QRect geom = s.value("obrowser/geometry", geometry()).toRect(); 00441 setGeometry(geom); 00442 } 00443 00444 void QObjectBrowser::set_object(QObject *obj) { 00445 if (!m_model.find_item(m_model.rootItem,obj)) //object is not valid 00446 m_control->set_object(0); 00447 else 00448 m_control->set_object(obj); 00449 } 00450 00451 void QObjectBrowser::on_current_item_changed() { 00452 QModelIndex index=m_tree->currentIndex(); 00453 if (!index.isValid()) return; 00454 QObjectTreeItem *item = static_cast<QObjectTreeItem*>(index.internalPointer()); 00455 if (!item) return; 00456 set_object(item->m_obj); 00457 } 00458 void QObjectBrowser::on_object_changed(QObject *obj) { 00459 QModelIndex index=m_model.getindex(obj); 00460 m_tree->setCurrentIndex(index); 00461 m_tree->scrollTo(index); 00462 } 00463 void QObjectBrowser::on_update() { 00464 m_model.refresh(); 00465 00466 00467 } 00468 void QObjectBrowser::on_focus_changed( QWidget *old, QWidget *now) { 00469 Q_UNUSED(old); 00470 if (!now) return; 00471 QWidget *ptr=now; 00472 while (ptr) { 00473 if (ptr==this) return; 00474 ptr=ptr->parentWidget(); 00475 } 00476 m_last_focus_window=now; 00477 } 00478 void QObjectBrowser::on_browse_focus() { 00479 if (m_last_focus_window) 00480 set_object(m_last_focus_window); 00481 else 00482 set_object(qApp->focusWidget()); 00483 } 00484 00485 QObject *QObjectBrowser::get_current_object() { 00486 QModelIndex index=m_tree->currentIndex(); 00487 if (!index.isValid()) return 0; 00488 QObjectTreeItem *item = static_cast<QObjectTreeItem*>(index.internalPointer()); 00489 if (!item) return 0; 00490 return item->m_obj; 00491 } 00492 00493 void QObjectBrowser::on_show_widget() { 00494 QObject *obj=get_current_object(); 00495 if (!obj) return; 00496 if (!obj->isWidgetType()) return; 00497 QWidget *W=(QWidget *)obj; 00498 W->show(); 00499 } 00500 00501 void QObjectBrowser::on_hide_widget() { 00502 QObject *obj=get_current_object(); 00503 if (!obj) return; 00504 if (!obj->isWidgetType()) return; 00505 QWidget *W=(QWidget *)obj; 00506 W->hide(); 00507 emit hidden(); 00508 } 00509 void QObjectBrowser::on_focus_widget() { 00510 QObject *obj=get_current_object(); 00511 if (!obj) return; 00512 if (!obj->isWidgetType()) return; 00513 QWidget *W=(QWidget *)obj; 00514 W->activateWindow(); 00515 W->setFocus(Qt::ActiveWindowFocusReason); 00516 } 00517 void QObjectBrowser::dumpObject() { 00518 QObject *obj = get_current_object(); 00519 obj->dumpObjectInfo(); 00520 }