Bug 128252

Summary: Input focus within process table should be on search field
Product: [Applications] ksysguard Reporter: Hans Meier <ma2412ma>
Component: generalAssignee: KSysGuard Developers <ksysguard-bugs>
Status: RESOLVED FIXED    
Severity: wishlist    
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: Ubuntu   
OS: Linux   
Latest Commit: Version Fixed In:

Description Hans Meier 2006-05-29 17:12:51 UTC
Version:            (using KDE KDE 3.5.2)
Installed from:    Ubuntu Packages

When starting up the process table, it would be very nice to have the keyboard input focus on the search field, because I often search for processes and have to select the search field first. Right now, the only tab is active, which is kind of useless.
Comment 1 Unknown 2006-11-25 12:01:10 UTC
Yes, I wish the field could get the focus, because when somebody opens the ProcessTable, s/he would like to kill an application and s/he has to click inside the input field.

I had wanted to open a new wish but I found this.
So, plus 1 vote :)
Comment 2 John Tapsell 2006-11-26 19:45:41 UTC
SVN commit 608084 by johnflux:

The nastiest, worsest, evilest bug fix ever to be invented this or any underworld domain.
Sets the focus to the search line when started with --showprocesses (i.e. when started with ctrl+esc)
Also fixes the tab ordering.

CCBUG:128252


 M  +38 -12    SensorDisplayLib/ProcessController.cc  
 M  +2 -0      SensorDisplayLib/ProcessController.h  
 M  +1 -13     SensorDisplayLib/SensorDisplay.cc  
 M  +0 -2      SensorDisplayLib/SensorDisplay.h  
 M  +4 -0      WorkSheet.cc  
 M  +3 -0      WorkSheet.h  
 M  +17 -6     Workspace.cc  
 M  +1 -1      Workspace.h  


--- branches/KDE/3.5/kdebase/ksysguard/gui/SensorDisplayLib/ProcessController.cc #608083:608084
@@ -65,11 +65,21 @@
 	dict.insert("Login", new QString(i18n("Login")));
 	dict.insert("Command", new QString(i18n("Command")));
 
+	// Setup the geometry management.
+	gm = new QVBoxLayout(this, 10);
+	Q_CHECK_PTR(gm);
+	gm->addSpacing(15);
+
+	gmSearch = new QHBoxLayout();
+	Q_CHECK_PTR(gmSearch);
+	gm->addLayout(gmSearch, 0);
+
 	// Create the table that lists the processes.
 	pList = new ProcessList(this, "pList");
 	Q_CHECK_PTR(pList);
 	pList->setShowSortIndicator(true);
 	pListSearchLine = new KListViewSearchLineWidget(pList, this, "process_list_search_line");
+	gmSearch->addWidget(pListSearchLine, 1);
 
 	connect(pList, SIGNAL(killProcess(int, int)),
 			this, SLOT(killProcess(int, int)));
@@ -83,6 +93,7 @@
 	 * pList constructor sets cbFilter to its start value. */
 	cbFilter = new QComboBox(this, "pList_cbFilter");
 	Q_CHECK_PTR(cbFilter);
+	gmSearch->addWidget(cbFilter,0);
 	cbFilter->insertItem(i18n("All Processes"), 0);
 	cbFilter->insertItem(i18n("System Processes"), 1);
 	cbFilter->insertItem(i18n("User Processes"), 2);
@@ -118,18 +129,6 @@
 	bKill->setEnabled(false);
 	killSupported = false;
 
-	
-	// Setup the geometry management.
-	gm = new QVBoxLayout(this, 10);
-	Q_CHECK_PTR(gm);
-	gm->addSpacing(15);
-
-	gmSearch = new QHBoxLayout();
-	Q_CHECK_PTR(gmSearch);
-	gm->addLayout(gmSearch, 0);
-	gmSearch->addWidget(pListSearchLine, 1);
-	gmSearch->addWidget(cbFilter,0);
-
 	gm->addWidget(pList, 1);
 
 	gm1 = new QHBoxLayout();
@@ -149,8 +148,35 @@
 	setPlotterWidget(pList);
 
 	setMinimumSize(sizeHint());
+	fixTabOrder(); 
 }
 
+void ProcessController::setSearchFocus() {
+	//stupid search line widget.  See rant in fixTabOrder
+	if(!pListSearchLine->searchLine())
+		QTimer::singleShot(100, this, SLOT(setSearchFocus()));
+	else {
+		pListSearchLine->searchLine()->setFocus();
+	}
+}
+void ProcessController::fixTabOrder() {
+
+	//Wow, I hate this search line widget so much.
+	//It creates the searchline in a singleshot timer.  This makes it totally unpredictable when searchLine is actually valid.
+	//So we set up singleshot timer and call ourselves over and over until it's ready.
+	//
+	//Did i mention I hate this?
+	if(!pListSearchLine->searchLine())
+		QTimer::singleShot(100, this, SLOT(fixTabOrder()));
+	else {
+		setTabOrder(pListSearchLine->searchLine(), cbFilter);
+		setTabOrder(cbFilter, pList);
+		setTabOrder(pList, xbTreeView);
+		setTabOrder(xbTreeView, bRefresh);
+		setTabOrder(bRefresh, bKill);
+	}
+}
+
 void
 ProcessController::resizeEvent(QResizeEvent* ev)
 {
--- branches/KDE/3.5/kdebase/ksysguard/gui/SensorDisplayLib/ProcessController.h #608083:608084
@@ -87,6 +87,8 @@
 	}
 
 public slots:
+	void setSearchFocus();
+	void fixTabOrder();
 	void filterModeChanged(int filter)
 	{
 		pList->setFilterMode(filter);
--- branches/KDE/3.5/kdebase/ksysguard/gui/SensorDisplayLib/SensorDisplay.cc #608083:608084
@@ -83,7 +83,6 @@
   /* Let's call updateWhatsThis() in case the derived class does not do
    * this. */
   updateWhatsThis();
-  setFocusPolicy( QWidget::StrongFocus );
 }
 
 SensorDisplay::~SensorDisplay()
@@ -431,18 +430,6 @@
   }
 }
 
-void SensorDisplay::focusInEvent( QFocusEvent* )
-{
-  if(mFrame)
-    mFrame->setLineWidth( 2 );
-}
-
-void SensorDisplay::focusOutEvent( QFocusEvent* )
-{
-  if(mFrame)
-    mFrame->setLineWidth( 1 );
-}
-
 void SensorDisplay::setSensorOk( bool ok )
 {
   if ( ok ) {
@@ -516,6 +503,7 @@
 void SensorDisplay::setPlotterWidget( QWidget *wdg )
 {
   mPlotterWdg = wdg;
+
 }
 
 QWidget *SensorDisplay::frame()
--- branches/KDE/3.5/kdebase/ksysguard/gui/SensorDisplayLib/SensorDisplay.h #608083:608084
@@ -238,8 +238,6 @@
 
   protected:
     virtual bool eventFilter( QObject*, QEvent* );
-    virtual void focusInEvent( QFocusEvent* );
-    virtual void focusOutEvent( QFocusEvent* );
     virtual void resizeEvent( QResizeEvent* );
     virtual void timerEvent( QTimerEvent* );
 
--- branches/KDE/3.5/kdebase/ksysguard/gui/WorkSheet.cc #608083:608084
@@ -634,6 +634,10 @@
   mGridLayout->activate();
 }
 
+KSGRD::SensorDisplay *WorkSheet::display( uint row, uint column ) {
+  if(row >= mRows || column >= mColumns) return 0;
+  return mDisplayList[row][column];
+}
 KSGRD::SensorDisplay *WorkSheet::currentDisplay( uint *row, uint *column )
 {
   for ( uint r = 0 ; r < mRows; ++r )
--- branches/KDE/3.5/kdebase/ksysguard/gui/WorkSheet.h #608083:608084
@@ -72,6 +72,9 @@
                                       const QString &sensorType,
                                       const QString &sensorDescr,
                                       uint rows, uint columns );
+    //Returns the sensor at position row,column.
+    //Return NULL if invalid row or column
+    KSGRD::SensorDisplay *display( uint row, uint column );
 
     void settings();
 
--- branches/KDE/3.5/kdebase/ksysguard/gui/Workspace.cc #608083:608084
@@ -35,6 +35,7 @@
 
 #include "WorkSheet.h"
 #include "WorkSheetSettings.h"
+#include "ProcessController.h"
 
 #include "Workspace.h"
 
@@ -341,7 +342,7 @@
     }
 }
 
-bool Workspace::restoreWorkSheet( const QString &fileName, const QString &newName )
+WorkSheet *Workspace::restoreWorkSheet( const QString &fileName, const QString &newName )
 {
   /* We might want to save the worksheet under a different name later. This
    * name can be specified by newName. If newName is empty we use the
@@ -365,7 +366,7 @@
 
   if ( !sheet->load( fileName ) ) {
     delete sheet;
-    return false;
+    return NULL;
   }
   
   mSheetList.append( sheet );
@@ -377,7 +378,7 @@
   if ( !newName.isEmpty() )
     sheet->setFileName( newName );
 
-  return true;
+  return sheet;
 }
 
 void Workspace::cut()
@@ -443,10 +444,20 @@
   kstd->addResourceType( "data", "share/apps/ksysguard" );
 
   QString file = kstd->findResource( "data", "ProcessTable.sgrd" );
-  if ( !file.isEmpty() )
-    restoreWorkSheet( file );
-  else
+  if ( file.isEmpty() ) {
     KMessageBox::error( this, i18n( "Cannot find file ProcessTable.sgrd." ) );
+    return;
+  }
+  WorkSheet *processSheet = restoreWorkSheet( file );
+  if(!processSheet) return;
+
+  //Set the focus of the search line.  This is nasty I know, but I don't know how better to do this :(
+  KSGRD::SensorDisplay *processSensor = processSheet->display( 0,0 );
+  if(!processSensor || !processSensor->isA("ProcessController")) return;
+  ProcessController *controller = dynamic_cast<ProcessController *>(processSensor);
+  if(!controller) return;
+  controller->setSearchFocus();
+
 }
 
 #include "Workspace.moc"
--- branches/KDE/3.5/kdebase/ksysguard/gui/Workspace.h #608083:608084
@@ -47,7 +47,7 @@
 
     void showProcesses();
 
-    bool restoreWorkSheet( const QString &fileName,
+    WorkSheet *restoreWorkSheet( const QString &fileName,
                            const QString &newName = QString::null );
     void deleteWorkSheet( const QString &fileName );
 
Comment 3 John Tapsell 2006-11-26 20:08:22 UTC
SVN commit 608097 by johnflux:

Focus the process search line on start up.
BUG:128252


 M  +4 -2      ProcessController.cc  


--- trunk/KDE/kdebase/workspace/ksysguard/gui/SensorDisplayLib/ProcessController.cc #608096:608097
@@ -234,7 +234,8 @@
 	 * requests are send whenever the sensor reconnects (detected in
 	 * sensorError(). */
 
-	mModel.setIsLocalhost(sensors().at(0)->isLocalhost()); //by telling our model that this is localhost, it can provide more information about the data it has
+	bool isLocalhost = sensors().at(0)->isLocalhost();
+	mModel.setIsLocalhost(isLocalhost); //by telling our model that this is localhost, it can provide more information about the data it has
 	
 	sensors().at(0)->setIsOk(true); //Assume it is okay from the start
 	setSensorOk(sensors().at(0)->isOk());
@@ -255,7 +256,8 @@
 		setTitle(i18n("%1: Running Processes", hostName));
 	else
 		setTitle(title);
-
+	if(isLocalhost)
+		QTimer::singleShot(0, mUi.txtFilter, SLOT(setFocus()));
 	return true;
 }