libyui  3.0.10
/usr/src/RPM/BUILD/libyui-3.0.10/src/YDialogSpy.cc
00001 /*
00002   Copyright (C) 2000-2012 Novell, Inc
00003   This library is free software; you can redistribute it and/or modify
00004   it under the terms of the GNU Lesser General Public License as
00005   published by the Free Software Foundation; either version 2.1 of the
00006   License, or (at your option) version 3.0 of the License. This library
00007   is distributed in the hope that it will be useful, but WITHOUT ANY
00008   WARRANTY; without even the implied warranty of MERCHANTABILITY or 
00009   FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
00010   License for more details. You should have received a copy of the GNU
00011   Lesser General Public License along with this library; if not, write
00012   to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
00013   Floor, Boston, MA 02110-1301 USA
00014 */
00015 
00016 
00017 /*-/
00018 
00019   File:         YDialogSpy.cc
00020 
00021   Author:       Stefan Hundhammer <sh@suse.de>
00022 
00023 /-*/
00024 
00025 #include <sstream>
00026 
00027 #define YUILogComponent "ui-dialog-spy"
00028 #include "YUILog.h"
00029 
00030 #include <YDialogSpy.h>
00031 #include <YWidgetFactory.h>
00032 #include <YDialog.h>
00033 #include <YEvent.h>
00034 #include <YTable.h>
00035 #include <YTree.h>
00036 #include <YTreeItem.h>
00037 #include <YLayoutBox.h>
00038 #include <YAlignment.h>
00039 #include <YButtonBox.h>
00040 #include <YPushButton.h>
00041 #include <YReplacePoint.h>
00042 #include <YUI.h>
00043 
00044 #define TREE_VWEIGHT    40
00045 #define PROP_VWEIGHT    60
00046 
00047 #define DIA_HEIGHT      24
00048 
00049 #define TREE_HEIGHT     10
00050 #define TREE_WIDTH      50
00051 
00052 #define PROP_HEIGHT     12
00053 #define PROP_WIDTH      50
00054 
00055 
00056 /**
00057  * Custom tree item class to map tree items to widgets
00058  **/
00059 class YWidgetTreeItem: public YTreeItem
00060 {
00061 public:
00062     YWidgetTreeItem( YWidget *  widget,
00063                      bool       isOpen )
00064         : YTreeItem( "", isOpen )
00065         , _widget( widget )
00066     {
00067         setWidgetLabel();
00068     }
00069 
00070     YWidgetTreeItem( YWidgetTreeItem *  parent,
00071                      YWidget *          widget,
00072                      bool               isOpen )
00073         : YTreeItem( parent, "", isOpen )
00074         , _widget( widget )
00075     {
00076         setWidgetLabel();
00077     }
00078 
00079     virtual ~YWidgetTreeItem() {}
00080     YWidget * widget() const { return _widget; }
00081 
00082 
00083 protected:
00084 
00085     void setWidgetLabel()
00086     {
00087         std::ostringstream str;
00088         str << _widget;
00089         setLabel( str.str() );
00090     }
00091 
00092 private:
00093     YWidget * _widget;
00094 };
00095 
00096 
00097 static void fillTree( YWidgetTreeItem *                 parent,
00098                       YWidgetListConstIterator          begin,
00099                       YWidgetListConstIterator          end,
00100                       int                               treeLevel );
00101 
00102 
00103 
00104 
00105 struct YDialogSpyPrivate
00106 {
00107     YDialogSpyPrivate()
00108         : targetDialog( 0 )
00109         , spyDialog( 0 )
00110         , widgetTree( 0 )
00111         , propButton( 0 )
00112         , propReplacePoint( 0 )
00113         , propTable( 0 )
00114         , closeButton( 0 )
00115         {}
00116 
00117     YDialog *           targetDialog;   // Dialog that is being inspected
00118     YDialog *           spyDialog;      // Debug dialog that shows widget data
00119     YTree *             widgetTree;     // Tree widget to show widget hierarchy
00120     YPushButton *       propButton;
00121     YReplacePoint *     propReplacePoint;
00122     YTable *            propTable;
00123     YPushButton *       closeButton;
00124 };
00125 
00126 
00127 
00128 YDialogSpy::YDialogSpy( YDialog * targetDialog )
00129     : priv( new YDialogSpyPrivate() )
00130 {
00131     if ( ! targetDialog )
00132         targetDialog = YDialog::topmostDialog();
00133 
00134     priv->targetDialog = targetDialog;
00135     YWidgetFactory * fac = YUI::widgetFactory();
00136 
00137     priv->spyDialog      = fac->createPopupDialog();
00138     YAlignment * diaMin  = fac->createMinHeight( priv->spyDialog, DIA_HEIGHT );
00139     YLayoutBox * vbox    = fac->createVBox( diaMin );
00140 
00141     YAlignment * minSize = fac->createMinSize( vbox, TREE_WIDTH, TREE_HEIGHT );
00142     minSize->setWeight( YD_VERT, TREE_VWEIGHT );
00143     priv->widgetTree     = fac->createTree( minSize, "Widget &Tree", false );
00144     priv->widgetTree->setNotify( true );
00145 
00146     YWidgetTreeItem * rootItem = new YWidgetTreeItem( targetDialog, true );
00147     YUI_CHECK_NEW( rootItem );
00148     fillTree( rootItem, targetDialog->childrenBegin(), targetDialog->childrenEnd(), 1 );
00149     priv->widgetTree->addItem( rootItem );
00150     priv->widgetTree->rebuildTree();
00151 
00152     YAlignment * alignment = fac->createLeft( vbox );
00153     priv->propButton       = fac->createPushButton( alignment, "&Properties >>>" );
00154     priv->propReplacePoint = fac->createReplacePoint( vbox );
00155     fac->createEmpty( priv->propReplacePoint );
00156 
00157     YButtonBox * buttonBox = fac->createButtonBox( vbox );
00158     priv->closeButton      = fac->createPushButton( buttonBox, "&Close" );
00159     priv->closeButton->setRole( YOKButton );
00160 }
00161 
00162 
00163 YDialogSpy::~YDialogSpy()
00164 {
00165     if ( priv->spyDialog )
00166         priv->spyDialog->destroy();
00167 }
00168 
00169 
00170 bool YDialogSpy::propertiesShown() const
00171 {
00172     return priv->propTable != 0;
00173 }
00174 
00175 
00176 void YDialogSpy::showProperties()
00177 {
00178     if ( ! propertiesShown() )
00179     {
00180         priv->propReplacePoint->deleteChildren();
00181         priv->propReplacePoint->setWeight( YD_VERT, PROP_VWEIGHT );
00182 
00183         YWidgetFactory * fac = YUI::widgetFactory();
00184         YAlignment * minSize = fac->createMinSize( priv->propReplacePoint,
00185                                                    PROP_WIDTH, PROP_HEIGHT );
00186         YTableHeader * header = new YTableHeader();
00187         YUI_CHECK_NEW( header );
00188         header->addColumn( "Property" );
00189         header->addColumn( "Value" );
00190         header->addColumn( "Type" );
00191 
00192         priv->propTable = fac->createTable( minSize, header );
00193         // priv->propTable->setKeepSorting( true );
00194 
00195         priv->propButton->setLabel( "<<< &Properties" );
00196         priv->propReplacePoint->showChild();
00197         priv->spyDialog->recalcLayout();
00198     }
00199 }
00200 
00201 
00202 void YDialogSpy::hideProperties()
00203 {
00204     if ( propertiesShown() )
00205     {
00206         priv->propReplacePoint->deleteChildren();
00207         priv->propReplacePoint->setWeight( YD_VERT, 0 );
00208         priv->propTable = 0;
00209         YUI::widgetFactory()->createEmpty( priv->propReplacePoint );
00210 
00211         priv->propButton->setLabel( "&Properties >>>" );
00212         priv->propReplacePoint->showChild();
00213         priv->spyDialog->recalcLayout();
00214     }
00215 }
00216 
00217 
00218 void YDialogSpy::showProperties( YWidget * widget )
00219 {
00220     if ( ! priv->propTable )
00221         return;
00222 
00223     priv->propTable->deleteAllItems();
00224 
00225     if ( widget )
00226     {
00227         YPropertySet propSet = widget->propertySet();
00228         YItemCollection items;
00229         items.reserve( propSet.size() );
00230 
00231         for ( YPropertySet::const_iterator it = propSet.propertiesBegin();
00232               it != propSet.propertiesEnd();
00233               ++it )
00234         {
00235             YProperty           prop    = *it;
00236             YPropertyValue      propVal = widget->getProperty( prop.name() );
00237             std::string         propValStr;
00238 
00239             switch ( prop.type() )
00240             {
00241                 case YStringProperty:
00242                     propValStr = propVal.stringVal();
00243                     break;
00244 
00245                 case YBoolProperty:
00246                     propValStr = propVal.boolVal() ? "true" : "false";
00247                     break;
00248 
00249                 case YIntegerProperty:
00250                     {
00251                         std::ostringstream str;
00252                         str << propVal.integerVal();
00253                         propValStr = str.str();
00254                     }
00255                     break;
00256 
00257                 default:
00258                     propValStr = "???";
00259                     break;
00260             }
00261 
00262             YTableItem * item = new YTableItem( prop.name(), propValStr, prop.typeAsStr() );
00263             YUI_CHECK_NEW( item );
00264             items.push_back( item );
00265         }
00266 
00267         priv->propTable->addItems( items );
00268         priv->propTable->deselectAllItems();
00269     }
00270 }
00271 
00272 
00273 void fillTree( YWidgetTreeItem *                parent,
00274                YWidgetListConstIterator         begin,
00275                YWidgetListConstIterator         end,
00276                int                              treeLevel )
00277 {
00278     for ( YWidgetListConstIterator it = begin; it != end; ++it )
00279     {
00280         YWidget * widget = *it;
00281         YWidgetTreeItem * item = new YWidgetTreeItem( parent, widget, treeLevel < 4 );
00282 
00283         if ( widget->hasChildren() )
00284             fillTree( item, widget->childrenBegin(), widget->childrenEnd(), treeLevel+1 );
00285     }
00286 }
00287 
00288 
00289 void YDialogSpy::exec()
00290 {
00291     YUI_CHECK_PTR( priv->spyDialog );
00292 
00293     while ( true )
00294     {
00295         bool updateProp = false;
00296         YEvent * event = priv->spyDialog->waitForEvent();
00297         yuiMilestone() << "dialog: " << priv->spyDialog->preferredHeight();
00298         yuiMilestone() << "tree: " << priv->widgetTree->preferredHeight();
00299 
00300         if ( event )
00301         {
00302             if ( event->widget()    == priv->closeButton ||
00303                  event->eventType() == YEvent::CancelEvent ) // window manager "close window" button
00304             {
00305                 priv->targetDialog->highlight( 0 );
00306                 return;
00307             }
00308 
00309             if ( event->widget() == priv->propButton )
00310             {
00311                 if ( propertiesShown() )
00312                     hideProperties();
00313                 else
00314                 {
00315                     showProperties();
00316                     updateProp = true;
00317                 }
00318             }
00319 
00320             if ( event->widget() == priv->widgetTree || updateProp )
00321             {
00322                 YWidgetTreeItem * item = (YWidgetTreeItem *) priv->widgetTree->selectedItem();
00323                 yuiDebug() << "Highlighting " << item << std::endl;
00324 
00325                 if ( item )
00326                 {
00327                     priv->targetDialog->highlight( item->widget() );
00328                     showProperties( item->widget() );
00329                 }
00330             }
00331         }
00332     }
00333 }
00334 
00335 
00336 void YDialogSpy::showDialogSpy( YDialog * dialog )
00337 {
00338     try
00339     {
00340         YDialogSpy dialogSpy( dialog );
00341         dialogSpy.exec();
00342     }
00343     catch ( YUIException & exception )
00344     {
00345         YUI_CAUGHT( exception );
00346     }
00347 }
 All Classes Functions Variables Enumerations Friends