2 KSysGuard, the KDE System Guard
4 Copyright (c) 1999 - 2001 Chris Schlaeger <cs@kde.org>
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public
8 License version 2 or at your option version 3 as published by
9 the Free Software Foundation.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 #include <QTextStream>
26 #include <QGridLayout>
29 #include <QDragEnterEvent>
32 #include <QApplication>
36 #include <kmessagebox.h>
39 #include <SensorManager.h>
41 #include "DancingBars.h"
42 #include "DummyDisplay.h"
43 #include "FancyPlotter.h"
46 #include "MultiMeter.h"
47 #include "ProcessController.h"
48 #include "SensorLogger.h"
49 #include "WorkSheet.h"
50 #include "WorkSheetSettings.h"
52 WorkSheet::WorkSheet( QWidget
*parent
)
59 mLocalProcessController
= NULL
;
60 setSizePolicy(QSizePolicy::Expanding
,QSizePolicy::Expanding
);
61 setAcceptDrops( true );
64 WorkSheet::WorkSheet( uint rows
, uint columns
, float interval
, QWidget
* parent
)
70 setUpdateInterval( interval
);
73 createGrid( rows
, columns
);
75 // Initialize worksheet with dummy displays.
76 for ( uint r
= 0; r
< mRows
; ++r
)
77 for ( uint c
= 0; c
< mColumns
; ++c
)
78 replaceDisplay( r
, c
);
80 mGridLayout
->activate();
82 setAcceptDrops( true );
85 WorkSheet::~WorkSheet()
87 for ( int r
= 0; r
< mRows
; ++r
) {
88 for ( int c
= 0; c
< mColumns
; ++c
)
89 delete mDisplayList
[ r
][ c
];
90 delete mDisplayList
[ r
];
92 delete [] mDisplayList
;
95 bool WorkSheet::load( const QString
&fileName
)
97 QFile
file( fileName
);
98 if ( !file
.open( QIODevice::ReadOnly
) ) {
99 KMessageBox::sorry( this, i18n( "Cannot open the file %1." , fileName
) );
105 // Read in file and check for a valid XML header.
106 if ( !doc
.setContent( &file
) ) {
107 KMessageBox::sorry( this, i18n( "The file %1 does not contain valid XML." ,
112 // Check for proper document type.
113 if ( doc
.doctype().name() != "KSysGuardWorkSheet" ) {
114 KMessageBox::sorry( this, i18n( "The file %1 does not contain a valid worksheet "
115 "definition, which must have a document type 'KSysGuardWorkSheet'.",
120 // Check for proper size.
121 QDomElement element
= doc
.documentElement();
122 float interval
= element
.attribute( "interval", "0.5" ).toFloat();
123 if( interval
<0.01 || interval
> 100000 ) //make sure the interval is fairly sane
126 setUpdateInterval(interval
);
128 mTitle
= element
.attribute( "title");
129 mTranslatedTitle
= mTitle
.isEmpty() ? "" : i18n(mTitle
.toUtf8());
131 mSharedSettings
.locked
= element
.attribute( "locked" ).toUInt( &ok
);
132 if(!ok
) mSharedSettings
.locked
= false;
134 bool rowsOk
, columnsOk
;
135 uint rows
= element
.attribute( "rows" ).toUInt( &rowsOk
);
136 uint columns
= element
.attribute( "columns" ).toUInt( &columnsOk
);
137 if ( !( rowsOk
&& columnsOk
) ) {
138 KMessageBox::sorry( this, i18n("The file %1 has an invalid worksheet size.",
143 createGrid( rows
, columns
);
146 /* Load lists of hosts that are needed for the work sheet and try
147 * to establish a connection. */
148 QDomNodeList dnList
= element
.elementsByTagName( "host" );
149 for ( i
= 0; i
< dnList
.count(); ++i
) {
150 QDomElement element
= dnList
.item( i
).toElement();
152 int port
= element
.attribute( "port" ).toInt( &ok
);
155 KSGRD::SensorMgr
->engage( element
.attribute( "name" ),
156 element
.attribute( "shell" ),
157 element
.attribute( "command" ), port
);
159 //if no hosts are specified, at least connect to localhost
160 if(dnList
.count() == 0)
161 KSGRD::SensorMgr
->engage( "localhost", "", "ksysguardd", -1);
163 // Load the displays and place them into the work sheet.
164 dnList
= element
.elementsByTagName( "display" );
165 for ( i
= 0; i
< dnList
.count(); ++i
) {
166 QDomElement element
= dnList
.item( i
).toElement();
167 uint row
= element
.attribute( "row" ).toUInt();
168 uint column
= element
.attribute( "column" ).toUInt();
169 if ( row
>= mRows
|| column
>= mColumns
) {
170 kDebug(1215) << "Row or Column out of range (" << row
<< ", "
171 << column
<< ")" << endl
;
174 replaceDisplay( row
, column
, element
);
177 // Fill empty cells with dummy displays
178 for ( uint r
= 0; r
< mRows
; ++r
)
179 for ( uint c
= 0; c
< mColumns
; ++c
)
180 if ( !mDisplayList
[ r
][ c
] )
181 replaceDisplay( r
, c
);
186 bool WorkSheet::save( const QString
&fileName
)
188 return exportWorkSheet(fileName
);
191 bool WorkSheet::exportWorkSheet( const QString
&fileName
)
193 QDomDocument
doc( "KSysGuardWorkSheet" );
194 doc
.appendChild( doc
.createProcessingInstruction(
195 "xml", "version=\"1.0\" encoding=\"UTF-8\"" ) );
197 // save work sheet information
198 QDomElement ws
= doc
.createElement( "WorkSheet" );
199 doc
.appendChild( ws
);
200 ws
.setAttribute( "title", mTitle
);
201 ws
.setAttribute( "locked", mSharedSettings
.locked
?"1":"0" );
202 ws
.setAttribute( "interval", updateInterval() );
203 ws
.setAttribute( "rows", mRows
);
204 ws
.setAttribute( "columns", mColumns
);
207 collectHosts( hosts
);
209 // save host information (name, shell, etc.)
210 QStringList::Iterator it
;
211 for ( it
= hosts
.begin(); it
!= hosts
.end(); ++it
) {
212 QString shell
, command
;
215 if ( KSGRD::SensorMgr
->hostInfo( *it
, shell
, command
, port
) ) {
216 QDomElement host
= doc
.createElement( "host" );
217 ws
.appendChild( host
);
218 host
.setAttribute( "name", *it
);
219 host
.setAttribute( "shell", shell
);
220 host
.setAttribute( "command", command
);
221 host
.setAttribute( "port", port
);
225 for ( uint r
= 0; r
< mRows
; ++r
)
226 for (uint c
= 0; c
< mColumns
; ++c
)
227 if ( QByteArray("DummyDisplay") != mDisplayList
[ r
][ c
]->metaObject()->className()) {
228 KSGRD::SensorDisplay
* display
= (KSGRD::SensorDisplay
*)mDisplayList
[ r
][ c
];
229 QDomElement element
= doc
.createElement( "display" );
230 ws
.appendChild( element
);
231 element
.setAttribute( "row", r
);
232 element
.setAttribute( "column", c
);
233 element
.setAttribute( "class", display
->metaObject()->className() );
235 display
->saveSettings( doc
, element
);
238 QFile
file( fileName
);
239 if ( !file
.open( QIODevice::WriteOnly
) ) {
240 KMessageBox::sorry( this, i18n( "Cannot save file %1" , fileName
) );
244 QTextStream
s( &file
);
245 s
.setCodec( "UTF-8" );
252 void WorkSheet::cut()
254 if ( !currentDisplay() || currentDisplay()->metaObject()->className() == QByteArray("DummyDisplay" ) )
257 QClipboard
* clip
= QApplication::clipboard();
259 clip
->setText( currentDisplayAsXML() );
261 removeDisplay( currentDisplay() );
264 void WorkSheet::copy()
266 if ( !currentDisplay() || currentDisplay()->metaObject()->className() == QByteArray( "DummyDisplay" ) )
269 QClipboard
* clip
= QApplication::clipboard();
271 clip
->setText( currentDisplayAsXML() );
274 void WorkSheet::paste()
277 if ( !currentDisplay( &row
, &column
) )
280 QClipboard
* clip
= QApplication::clipboard();
283 /* Get text from clipboard and check for a valid XML header and
284 * proper document type. */
285 if ( !doc
.setContent( clip
->text() ) || doc
.doctype().name() != "KSysGuardDisplay" ) {
286 KMessageBox::sorry( this, i18n("The clipboard does not contain a valid display "
291 QDomElement element
= doc
.documentElement();
292 replaceDisplay( row
, column
, element
);
295 void WorkSheet::setFileName( const QString
&fileName
)
297 mFileName
= fileName
;
300 QString
WorkSheet::fileName() const
305 void WorkSheet::setTitle( const QString
&title
)
308 mTranslatedTitle
= mTitle
.isEmpty() ? "" : i18n(mTitle
.toUtf8());
309 emit
titleChanged(this);
312 QString
WorkSheet::translatedTitle() const {
313 return mTranslatedTitle
;
316 QString
WorkSheet::title() const {
320 KSGRD::SensorDisplay
*WorkSheet::addDisplay( const QString
&hostName
,
321 const QString
&sensorName
,
322 const QString
&sensorType
,
323 const QString
& sensorDescr
,
324 uint row
, uint column
)
327 /* If the by 'row' and 'column' specified display is a QGroupBox dummy
328 * display we replace the widget. Otherwise we just try to add
329 * the new sensor to an existing display. */
330 if ( mDisplayList
[ row
][ column
]->metaObject()->className() == QByteArray( "DummyDisplay" ) ) {
331 KSGRD::SensorDisplay
* newDisplay
= 0;
332 /* If the sensor type is supported by more than one display
333 * type we popup a menu so the user can select what display is
335 if ( sensorType
== "integer" || sensorType
== "float" ) {
337 pm
.addTitle( i18n( "Select Display Type" ) );
338 QAction
*a1
= pm
.addAction( i18n( "&Line graph" ) );
339 QAction
*a2
= pm
.addAction( i18n( "&Digital display" ) );
340 QAction
*a3
= pm
.addAction( i18n( "&Bar graph" ) );
341 QAction
*a4
= pm
.addAction( i18n( "Log to a &file" ) );
342 QAction
*execed
= pm
.exec( QCursor::pos() );
344 newDisplay
= new FancyPlotter( this, sensorDescr
, &mSharedSettings
);
346 else if (execed
== a2
) {
347 newDisplay
= new MultiMeter( this, sensorDescr
, &mSharedSettings
);
349 else if (execed
== a3
) {
350 newDisplay
= new DancingBars( this, sensorDescr
, &mSharedSettings
);
352 else if (execed
== a4
) {
353 newDisplay
= new SensorLogger( this, sensorDescr
, &mSharedSettings
);
358 } else if ( sensorType
== "listview" ) {
359 newDisplay
= new ListView( this, sensorDescr
, &mSharedSettings
);
361 else if ( sensorType
== "logfile" ) {
362 newDisplay
= new LogFile( this, sensorDescr
, &mSharedSettings
);
364 else if ( sensorType
== "sensorlogger" ) {
365 newDisplay
= new SensorLogger( this, sensorDescr
, &mSharedSettings
);
367 else if ( sensorType
== "table" ) {
368 if(!mLocalProcessController
&& (hostName
.isEmpty() || hostName
== "localhost")) {
369 mLocalProcessController
= new ProcessController( this, sensorDescr
, &mSharedSettings
);
370 newDisplay
= mLocalProcessController
;
372 newDisplay
= new ProcessController( this, sensorDescr
, &mSharedSettings
);
375 kDebug(1215) << "Unknown sensor type: " << sensorType
;
379 newDisplay
->applyStyle();
381 connect(&mTimer
, SIGNAL( timeout()), newDisplay
, SLOT( timerTick()));
382 replaceDisplay( row
, column
, newDisplay
);
385 mDisplayList
[ row
][ column
]->addSensor( hostName
, sensorName
, sensorType
, sensorDescr
);
387 return ((KSGRD::SensorDisplay
*)mDisplayList
[ row
][ column
] );
390 void WorkSheet::settings()
392 WorkSheetSettings
dlg( this, mSharedSettings
.locked
);
393 dlg
.setSheetTitle( mTranslatedTitle
);
394 dlg
.setInterval( updateInterval() );
396 if(!mSharedSettings
.locked
) {
397 dlg
.setRows( mRows
);
398 dlg
.setColumns( mColumns
);
402 setUpdateInterval( dlg
.interval() );
404 if (!mSharedSettings
.locked
)
405 resizeGrid( dlg
.rows(), dlg
.columns() );
407 if(mTranslatedTitle
!= dlg
.sheetTitle()) { //Title has changed
408 if(mRows
== 1 && mColumns
==1) {
409 mDisplayList
[ 0 ][ 0 ]->setTitle(dlg
.sheetTitle());
411 setTitle(dlg
.sheetTitle());
417 void WorkSheet::showPopupMenu( KSGRD::SensorDisplay
*display
)
419 display
->configureSettings();
422 void WorkSheet::applyStyle()
424 for ( uint r
= 0; r
< mRows
; ++r
)
425 for (uint c
= 0; c
< mColumns
; ++c
)
426 mDisplayList
[ r
][ c
]->applyStyle();
429 void WorkSheet::dragEnterEvent( QDragEnterEvent
* event
)
431 if ( !event
->mimeData()->hasFormat("application/x-ksysguard") )
435 void WorkSheet::dragMoveEvent( QDragMoveEvent
*event
)
438 /* Find the sensor display that is supposed to get the drop
439 * event and replace or add sensor. */
440 const QPoint globalPos
= mapToGlobal( event
->pos() );
441 for ( uint r
= 0; r
< mRows
; ++r
) {
442 for ( uint c
= 0; c
< mColumns
; ++c
) {
443 const QSize displaySize
= mDisplayList
[ r
][ c
]->size();
445 const QPoint
displayPoint( displaySize
.width(), displaySize
.height() );
447 const QRect widgetRect
= QRect( mDisplayList
[ r
][ c
]->mapToGlobal( QPoint( 0, 0 ) ),
448 mDisplayList
[ r
][ c
]->mapToGlobal( displayPoint
) );
451 if ( widgetRect
.contains( globalPos
) ) {
452 QByteArray widgetType
= mDisplayList
[ r
][ c
]->metaObject()->className();
453 if(widgetType
== "MultiMeter" || widgetType
== "ProcessController" || widgetType
== "table")
454 event
->ignore(widgetRect
);
455 else if(widgetType
!= "Dumm")
456 event
->accept(widgetRect
);
463 void WorkSheet::dropEvent( QDropEvent
*event
)
465 if ( !event
->mimeData()->hasFormat("application/x-ksysguard") )
468 const QString dragObject
= QString::fromUtf8(event
->mimeData()->data("application/x-ksysguard"));
470 // The host name, sensor name and type are separated by a ' '.
471 QStringList parts
= dragObject
.split( ' ');
473 QString hostName
= parts
[ 0 ];
474 QString sensorName
= parts
[ 1 ];
475 QString sensorType
= parts
[ 2 ];
476 QString sensorDescr
= parts
[ 3 ];
478 if ( hostName
.isEmpty() || sensorName
.isEmpty() || sensorType
.isEmpty() )
481 /* Find the sensor display that is supposed to get the drop
482 * event and replace or add sensor. */
483 const QPoint globalPos
= mapToGlobal( event
->pos() );
484 for ( uint r
= 0; r
< mRows
; ++r
) {
485 for ( uint c
= 0; c
< mColumns
; ++c
) {
486 const QSize displaySize
= mDisplayList
[ r
][ c
]->size();
488 const QPoint
displayPoint( displaySize
.width(), displaySize
.height() );
490 const QRect widgetRect
= QRect( mDisplayList
[ r
][ c
]->mapToGlobal( QPoint( 0, 0 ) ),
491 mDisplayList
[ r
][ c
]->mapToGlobal( displayPoint
) );
494 if ( widgetRect
.contains( globalPos
) ) {
495 addDisplay( hostName
, sensorName
, sensorType
, sensorDescr
, r
, c
);
502 QSize
WorkSheet::sizeHint() const
504 return QSize( 800,600 );
507 bool WorkSheet::event( QEvent
*e
)
509 if ( e
->type() == QEvent::User
) {
510 // SensorDisplays send out this event if they want to be removed.
511 if ( KMessageBox::warningContinueCancel( this, i18n( "Do you really want to delete the display?" ),
512 i18n("Delete Display"), KStandardGuiItem::del() )
513 == KMessageBox::Continue
) {
514 KSGRD::SensorDisplay::DeleteEvent
*event
= static_cast<KSGRD::SensorDisplay::DeleteEvent
*>( e
);
515 removeDisplay( event
->display() );
521 return QWidget::event( e
);
524 bool WorkSheet::replaceDisplay( uint row
, uint column
, QDomElement
& element
)
526 QString classType
= element
.attribute( "class" );
527 KSGRD::SensorDisplay
* newDisplay
= 0;
530 if ( classType
== "FancyPlotter" ) {
531 newDisplay
= new FancyPlotter( 0, i18n("Dummy"), &mSharedSettings
);
533 else if ( classType
== "MultiMeter" )
534 newDisplay
= new MultiMeter( 0, i18n("Dummy"), &mSharedSettings
);
535 else if ( classType
== "DancingBars" )
536 newDisplay
= new DancingBars( 0, i18n("Dummy"), &mSharedSettings
);
537 else if ( classType
== "ListView" )
538 newDisplay
= new ListView( 0, i18n("Dummy"), &mSharedSettings
);
539 else if ( classType
== "LogFile" )
540 newDisplay
= new LogFile( 0, i18n("Dummy"), &mSharedSettings
);
541 else if ( classType
== "SensorLogger" )
542 newDisplay
= new SensorLogger( 0, i18n("Dummy"), &mSharedSettings
);
543 else if ( classType
== "ProcessController" ) {
544 if(!mLocalProcessController
) {
545 kDebug() << "Found process controller";
546 mLocalProcessController
= new ProcessController( 0, i18n("Dummy"), &mSharedSettings
);
547 newDisplay
= mLocalProcessController
;
550 kDebug(1215) << "Unknown class " << classType
;
554 connect(&mTimer
, SIGNAL( timeout()), newDisplay
, SLOT( timerTick()));
556 // load display specific settings
557 if ( !newDisplay
->restoreSettings( element
) )
560 replaceDisplay( row
, column
, newDisplay
);
566 void WorkSheet::replaceDisplay( uint row
, uint column
, KSGRD::SensorDisplay
* newDisplay
)
568 // remove the old display && sensor frame at this location
569 if ( mDisplayList
[ row
][ column
] ) {
570 if(mDisplayList
[ row
][ column
] == mLocalProcessController
)
571 mLocalProcessController
= NULL
;
572 if ( qstrcmp( mDisplayList
[ row
][ column
]->parent()->metaObject()->className(), "SensorFrame" ) == 0 ) {
573 delete mDisplayList
[ row
][ column
]->parent(); // destroys the child (display) as well
575 delete mDisplayList
[ row
][ column
];
579 // insert new display
581 newDisplay
= new DummyDisplay( this, &mSharedSettings
);
582 mDisplayList
[ row
][ column
] = newDisplay
;
584 mDisplayList
[ row
][ column
] = newDisplay
;
585 connect( newDisplay
, SIGNAL( showPopupMenu( KSGRD::SensorDisplay
* ) ),
586 SLOT( showPopupMenu( KSGRD::SensorDisplay
* ) ) );
587 newDisplay
->setDeleteNotifier( this );
590 mGridLayout
->addWidget( mDisplayList
[ row
][ column
], row
, column
);
591 if(mRows
== 1 && mColumns
== 1) { //if there's only item, the tab's title should be the widget's title
592 connect( newDisplay
, SIGNAL(titleChanged(const QString
&)), SLOT(setTitle(const QString
&)));
593 setTitle(newDisplay
->title());
596 mDisplayList
[ row
][ column
]->show();
600 void WorkSheet::removeDisplay( KSGRD::SensorDisplay
*display
)
605 if(display
== mLocalProcessController
)
606 mLocalProcessController
= NULL
;
608 for ( uint r
= 0; r
< mRows
; ++r
)
609 for ( uint c
= 0; c
< mColumns
; ++c
)
610 if ( mDisplayList
[ r
][ c
] == display
) {
611 replaceDisplay( r
, c
);
616 void WorkSheet::collectHosts( QStringList
&list
)
618 for ( uint r
= 0; r
< mRows
; ++r
)
619 for ( uint c
= 0; c
< mColumns
; ++c
)
620 if ( mDisplayList
[ r
][ c
]->metaObject()->className() != QByteArray( "DummyDisplay" ) )
621 ((KSGRD::SensorDisplay
*)mDisplayList
[ r
][ c
])->hosts( list
);
624 void WorkSheet::createGrid( uint rows
, uint columns
)
629 // create grid layout with specified dimensions
630 mGridLayout
= new QGridLayout( this );
631 mGridLayout
->setSpacing( 5 );
633 mDisplayList
= new KSGRD::SensorDisplay
**[ mRows
];
634 for ( uint r
= 0; r
< mRows
; ++r
) {
635 mDisplayList
[ r
] = new KSGRD::SensorDisplay
*[ mColumns
];
636 for ( uint c
= 0; c
< mColumns
; ++c
)
637 mDisplayList
[ r
][ c
] = 0;
640 /* set stretch factors for rows and columns */
641 for ( uint r
= 0; r
< mRows
; ++r
)
642 mGridLayout
->setRowStretch( r
, 100 );
643 for ( uint c
= 0; c
< mColumns
; ++c
)
644 mGridLayout
->setColumnStretch( c
, 100 );
647 void WorkSheet::resizeGrid( uint newRows
, uint newColumns
)
651 /* Create new array for display pointers */
652 KSGRD::SensorDisplay
*** newDisplayList
= new KSGRD::SensorDisplay
**[ newRows
];
653 for ( r
= 0; r
< newRows
; ++r
) {
654 newDisplayList
[ r
] = new KSGRD::SensorDisplay
*[ newColumns
];
655 for ( c
= 0; c
< newColumns
; ++c
) {
656 if ( c
< mColumns
&& r
< mRows
)
657 newDisplayList
[ r
][ c
] = mDisplayList
[ r
][ c
];
659 newDisplayList
[ r
][ c
] = 0;
663 /* remove obsolete displays */
664 for ( r
= 0; r
< mRows
; ++r
) {
665 for ( c
= 0; c
< mColumns
; ++c
)
666 if ( r
>= newRows
|| c
>= newColumns
)
667 delete mDisplayList
[ r
][ c
];
668 delete mDisplayList
[ r
];
670 delete [] mDisplayList
;
672 /* now we make the new display the regular one */
673 mDisplayList
= newDisplayList
;
675 /* create new displays */
676 for ( r
= 0; r
< newRows
; ++r
)
677 for ( c
= 0; c
< newColumns
; ++c
)
678 if ( r
>= mRows
|| c
>= mColumns
)
679 replaceDisplay( r
, c
);
681 /* set stretch factors for new rows and columns (if any) */
682 for ( r
= mRows
; r
< newRows
; ++r
)
683 mGridLayout
->setRowStretch( r
, 100 );
684 for ( c
= mColumns
; c
< newColumns
; ++c
)
685 mGridLayout
->setColumnStretch( c
, 100 );
687 /* Obviously Qt does not shrink the size of the QGridLayout
688 * automatically. So we simply force the rows and columns that
689 * are no longer used to have a stretch factor of 0 and hence be
691 for ( r
= newRows
; r
< mRows
; ++r
)
692 mGridLayout
->setRowStretch( r
, 0 );
693 for ( c
= newColumns
; c
< mColumns
; ++c
)
694 mGridLayout
->setColumnStretch( c
, 0 );
697 mColumns
= newColumns
;
701 mGridLayout
->activate();
704 KSGRD::SensorDisplay
*WorkSheet::currentDisplay( uint
*row
, uint
*column
)
706 for ( uint r
= 0 ; r
< mRows
; ++r
)
707 for ( uint c
= 0 ; c
< mColumns
; ++c
)
708 if ( mDisplayList
[ r
][ c
]->hasFocus() ) {
713 return ( mDisplayList
[ r
][ c
] );
719 void WorkSheet::fixTabOrder()
721 for ( uint r
= 0; r
< mRows
; ++r
)
722 for ( uint c
= 0; c
< mColumns
; ++c
) {
723 if ( c
+ 1 < mColumns
)
724 setTabOrder( mDisplayList
[ r
][ c
], mDisplayList
[ r
][ c
+ 1 ] );
725 else if ( r
+ 1 < mRows
)
726 setTabOrder( mDisplayList
[ r
][ c
], mDisplayList
[ r
+ 1 ][ 0 ] );
730 QString
WorkSheet::currentDisplayAsXML()
732 KSGRD::SensorDisplay
* display
= currentDisplay();
736 /* We create an XML description of the current display. */
737 QDomDocument
doc( "KSysGuardDisplay" );
738 doc
.appendChild( doc
.createProcessingInstruction(
739 "xml", "version=\"1.0\" encoding=\"UTF-8\"" ) );
741 QDomElement element
= doc
.createElement( "display" );
742 doc
.appendChild( element
);
743 element
.setAttribute( "class", display
->metaObject()->className() );
744 display
->saveSettings( doc
, element
);
746 return doc
.toString();
749 void WorkSheet::changeEvent( QEvent
* event
) {
750 if (event
->type() == QEvent::LanguageChange
) {
751 setTitle(mTitle
); //retranslate
755 void WorkSheet::setUpdateInterval( float secs
)
760 mTimer
.setInterval(secs
*1000);
764 float WorkSheet::updateInterval() const
766 if(mTimer
.isActive())
767 return mTimer
.interval()/1000.0;
772 #include "WorkSheet.moc"