//Author: Timothy Pearson <kb9vqf@pearsoncomputing.net>, (C) 2012
//Copyright: See COPYING file that comes with this distribution
// TDE MDI interface based on excellent tutorial by Andrea Bergia et al.
# include "remotemdi.h"
# include <cassert>
using namespace std ;
# include <kapplication.h>
# include <klocale.h>
# include <kdebug.h>
# include <kconfig.h>
# include <tqlabel.h>
# include <tqtimer.h>
# include <tqlayout.h>
# include <kiconloader.h>
# include <kstdaction.h>
# include <kstatusbar.h>
# include <kmdichildview.h>
# include <klistbox.h>
# include <kactionclasses.h>
# include <kedittoolbar.h>
# include <kkeydialog.h>
# include "views/instrumentview.h"
RemoteMDI : : RemoteMDI ( )
: KMdiMainFrm ( 0 , " RemoteMDI " , KMdi : : ChildframeMode ) , m_children ( NULL ) , m_rsvSvrSocket ( NULL )
{
setXMLFile ( " remotelabui.rc " ) ;
// Create some actions
KStdAction : : close ( this , SLOT ( closeCurrent ( ) ) , actionCollection ( ) ) ;
KStdAction : : quit ( this , SLOT ( close ( ) ) , actionCollection ( ) ) ;
KActionCollection * const ac = actionCollection ( ) ;
setStandardToolBarMenuEnabled ( true ) ;
KStdAction : : quit ( TQT_TQOBJECT ( this ) , TQT_SLOT ( close ( ) ) , ac ) ;
KStdAction : : configureToolbars ( TQT_TQOBJECT ( this ) , TQT_SLOT ( configToolbars ( ) ) , ac ) ;
KStdAction : : keyBindings ( TQT_TQOBJECT ( this ) , TQT_SLOT ( configKeys ( ) ) , ac ) ;
connect_action = new KAction ( i18n ( " Connect to Server " ) , " connect_creating " , NULL , TQT_TQOBJECT ( this ) , TQT_SLOT ( connectToServer ( ) ) , ac , " connect_server " ) ;
disconnect_action = new KAction ( i18n ( " Disconnect from Server " ) , " connect_no " , NULL , TQT_TQOBJECT ( this ) , TQT_SLOT ( disconnectFromServer ( ) ) , ac , " disconnect_server " ) ;
inst_sa_menu = new KAction ( i18n ( " Launch Spectrum Analyzer " ) , " remote " , NULL , TQT_TQOBJECT ( this ) , TQT_SLOT ( startSpectrumAnalyzer ( ) ) , ac , " spectrum_analyzer " ) ;
// Add Window menu
if ( ! isFakingSDIApplication ( ) ) {
menuBar ( ) - > insertItem ( i18n ( " &Window " ) , windowMenu ( ) ) ;
}
createGUI ( 0 ) ;
// When we change view, change the status bar text
connect ( this , SIGNAL ( viewActivated ( KMdiChildView * ) ) , this , SLOT ( currentChanged ( KMdiChildView * ) ) ) ;
ac - > setHighlightingEnabled ( true ) ;
connect ( ac , TQT_SIGNAL ( actionStatusText ( const TQString & ) ) , statusBar ( ) , TQT_SLOT ( message ( const TQString & ) ) ) ;
connect ( ac , TQT_SIGNAL ( clearStatusText ( ) ) , statusBar ( ) , TQT_SLOT ( clear ( ) ) ) ;
// Create the status bar
statusBar ( ) - > message ( i18n ( " No view! " ) ) ;
// Create the list of the opened windows
m_listBox = new KListBox ( this ) ;
m_listBox - > setCaption ( i18n ( " Opened windows " ) ) ;
addToolWindow ( m_listBox , KDockWidget : : DockLeft , getMainDockWidget ( ) ) ;
connect ( m_listBox , SIGNAL ( executed ( TQListBoxItem * ) ) , this , SLOT ( listBoxExecuted ( TQListBoxItem * ) ) ) ;
connect ( m_listBox , SIGNAL ( rightButtonClicked ( TQListBoxItem * , const TQPoint & ) ) , this , SLOT ( listBoxRightClicked ( TQListBoxItem * ) ) ) ;
processLockouts ( ) ;
}
RemoteMDI : : ~ RemoteMDI ( )
{
while ( m_pCurrentWindow ) {
closeCurrent ( ) ;
}
if ( m_rsvSvrSocket ) {
m_rsvSvrSocket - > close ( ) ;
while ( m_rsvSvrSocket - > state ( ) = = TQSocket : : Closing ) {
tqApp - > processEvents ( ) ;
}
delete m_rsvSvrSocket ;
}
}
void RemoteMDI : : connectToServer ( ) {
if ( m_rsvSvrSocket ) {
return ;
}
connect_action - > setEnabled ( false ) ;
disconnect_action - > setEnabled ( false ) ;
// Connect to the central reservation/control server
m_rsvSvrSocket = new TDEKerberosClientSocket ( this ) ;
connect ( m_rsvSvrSocket , SIGNAL ( connectionClosed ( ) ) , this , SLOT ( connectionClosedHandler ( ) ) ) ;
m_rsvSvrSocket - > setServiceName ( " remotefpga " ) ;
if ( m_serverHost ! = " " ) {
m_rsvSvrSocket - > setServerFQDN ( m_serverHost ) ;
m_rsvSvrSocket - > connectToHost ( m_serverHost , 4004 ) ;
while ( ( m_rsvSvrSocket - > state ( ) = = TQSocket : : Connecting ) | | ( m_rsvSvrSocket - > state ( ) = = TQSocket : : HostLookup ) ) {
tqApp - > processEvents ( ) ;
}
if ( m_rsvSvrSocket - > state ( ) = = TQSocket : : Connected ) {
printf ( " [DEBUG] Initial connection established... \n \r " ) ; fflush ( stdout ) ;
if ( m_rsvSvrSocket - > setUsingKerberos ( true ) ! = 0 ) {
disconnectFromServer ( ) ;
}
else {
// Connection established!
disconnect_action - > setEnabled ( true ) ;
// Read the next line from the server
TQString str = m_rsvSvrSocket - > readLine ( ) ;
printf ( " [RAJA DEBUG 200.0] Got %s \n \r " , str . ascii ( ) ) ; fflush ( stdout ) ;
}
}
else {
printf ( " [ERROR] Initial connection failed (state %d) \n \r " , m_rsvSvrSocket - > state ( ) ) ; fflush ( stdout ) ;
disconnectFromServer ( ) ;
}
}
processLockouts ( ) ;
}
void RemoteMDI : : disconnectFromServer ( ) {
connect_action - > setEnabled ( false ) ;
disconnect_action - > setEnabled ( false ) ;
if ( m_rsvSvrSocket ) {
m_rsvSvrSocket - > close ( ) ;
while ( m_rsvSvrSocket - > state ( ) = = TQSocket : : Closing ) {
tqApp - > processEvents ( ) ;
}
delete m_rsvSvrSocket ;
m_rsvSvrSocket = 0 ;
}
connect_action - > setEnabled ( true ) ;
processLockouts ( ) ;
}
void RemoteMDI : : connectionClosedHandler ( ) {
disconnectFromServer ( ) ;
}
void RemoteMDI : : processLockouts ( ) {
bool connected = false ;
if ( m_rsvSvrSocket ) {
connected = ( m_rsvSvrSocket - > state ( ) = = TQSocket : : Connected ) ;
}
printf ( " [RAJA DEBUG 600.0] connected: %d \n \r " , connected ) ; fflush ( stdout ) ;
connect_action - > setEnabled ( ! connected ) ;
disconnect_action - > setEnabled ( connected ) ;
inst_sa_menu - > setEnabled ( connected ) ;
}
void RemoteMDI : : configToolbars ( ) {
KEditToolbar dialog ( factory ( ) , this ) ;
dialog . showButtonApply ( false ) ;
if ( dialog . exec ( ) ) {
applyMainWindowSettings ( kapp - > config ( ) , " window " ) ;
}
}
void RemoteMDI : : configKeys ( ) {
KKeyDialog : : configure ( actionCollection ( ) , this ) ;
}
void RemoteMDI : : setServerHost ( TQString server ) {
m_serverHost = server ;
}
void RemoteMDI : : startSpectrumAnalyzer ( ) {
RemoteLab : : InstrumentView * saview = new RemoteLab : : InstrumentView ( " libremotelab_commanalyzer " , i18n ( " Communications Analyzer " ) , ( mdiMode ( ) = = KMdi : : ToplevelMode ) ? 0 : this ) ;
openNewWindow ( saview ) ;
if ( m_serverHost ! = " " ) {
saview - > connectServer ( m_serverHost ) ;
}
}
void RemoteMDI : : openNewWindow ( KMdiChildView * view )
{
// Add a child view
m_children + + ;
// The child view will be our child only if we aren't in Toplevel mode
if ( ! view ) {
view = new KMdiChildView ( i18n ( " View %1 " ) . arg ( m_children ) , ( mdiMode ( ) = = KMdi : : ToplevelMode ) ? 0 : this ) ;
}
( new TQHBoxLayout ( view ) ) - > setAutoAdd ( true ) ;
// Add the item to the window list
m_window . append ( view ) ;
m_listBox - > insertItem ( view - > tabCaption ( ) ) ;
// Add to the MDI and set as current
if ( mdiMode ( ) = = KMdi : : ToplevelMode ) {
addWindow ( view , KMdi : : Detach ) ;
}
else {
addWindow ( view ) ;
}
currentChanged ( view ) ;
// Handle termination
connect ( view , SIGNAL ( childWindowCloseRequest ( KMdiChildView * ) ) , this , SLOT ( childClosed ( KMdiChildView * ) ) ) ;
}
void RemoteMDI : : childWindowCloseRequest ( KMdiChildView * pWnd ) {
RemoteLab : : InstrumentView * iview = dynamic_cast < RemoteLab : : InstrumentView * > ( pWnd ) ;
if ( iview ) {
iview - > closeConnections ( ) ;
iview - > hide ( ) ;
// Give the child a chance to finish what it was doing
// FIXME HACK
// There is no nice way to shut down the instrument parts it seems...
// Debug why they crash when this delay is set to zero!
m_closelist . append ( pWnd ) ;
TQTimer : : singleShot ( 100 , this , SLOT ( processCloseList ( ) ) ) ;
}
}
void RemoteMDI : : processCloseList ( ) {
if ( m_closelist . begin ( ) ! = m_closelist . end ( ) ) {
KMdiMainFrm : : childWindowCloseRequest ( * m_closelist . begin ( ) ) ;
}
}
void RemoteMDI : : currentChanged ( KMdiChildView * current )
{
// Update status bar and list box
statusBar ( ) - > message ( i18n ( " %1 activated " ) . arg ( current - > tabCaption ( ) ) ) ;
TQListBoxItem * item = m_listBox - > findItem ( current - > tabCaption ( ) ) ;
assert ( item ) ;
m_listBox - > setCurrentItem ( item ) ;
}
void RemoteMDI : : closeCurrent ( )
{
// If there's a current view, close it
if ( m_pCurrentWindow ! = 0 ) {
// Notify the status bar of the removal of the window
statusBar ( ) - > message ( i18n ( " %1 removed " ) . arg ( m_pCurrentWindow - > tabCaption ( ) ) ) ;
// Remove from the window list
m_window . remove ( m_window . find ( m_pCurrentWindow ) ) ;
// Remove from the list box
TQListBoxItem * item = m_listBox - > findItem ( m_pCurrentWindow - > tabCaption ( ) ) ;
assert ( item ) ;
delete item ;
// We could also call removeWindowFromMdi, but it doesn't delete the
// pointer. This way, we're sure that the view will get deleted.
closeWindow ( m_pCurrentWindow ) ;
}
// Synchronize combo box
if ( m_pCurrentWindow ) {
currentChanged ( m_pCurrentWindow ) ;
}
}
void RemoteMDI : : listBoxExecuted ( TQListBoxItem * item )
{
// Get the current item's text
TQString text = item - > text ( ) ;
// Active the corresponding tab
for ( TQValueList < KMdiChildView * > : : iterator it = m_window . begin ( ) ; it ! = m_window . end ( ) ; + + it ) {
// Get the view
KMdiChildView * view = * it ;
assert ( view ) ;
// Is the view we need to show?
if ( view - > caption ( ) = = text ) {
view - > activate ( ) ;
break ;
}
}
}
void RemoteMDI : : listBoxRightClicked ( TQListBoxItem * item )
{
// Get the current item's text
TQString text = item - > text ( ) ;
// Bring up a menu for the corresponding window
// RAJA FIXME
for ( TQValueList < KMdiChildView * > : : iterator it = m_window . begin ( ) ; it ! = m_window . end ( ) ; + + it ) {
// Get the view
KMdiChildView * view = * it ;
assert ( view ) ;
// Is the view we need to show?
if ( view - > caption ( ) = = text ) {
view - > activate ( ) ;
break ;
}
}
}
void RemoteMDI : : childClosed ( KMdiChildView * w )
{
assert ( w ) ;
// Set as active
w - > activate ( ) ;
assert ( w = = m_pCurrentWindow ) ;
// Notify the status bar of the removal of the window
statusBar ( ) - > message ( i18n ( " %1 removed " ) . arg ( w - > tabCaption ( ) ) ) ;
// Remove from the window list
m_window . remove ( m_window . find ( w ) ) ;
// Remove from the list box
TQListBoxItem * item = m_listBox - > findItem ( w - > tabCaption ( ) ) ;
assert ( item ) ;
delete item ;
// Remove the view from MDI, BUT DO NOT DELETE IT! It is automatically deleted by TQt since it was closed.
removeWindowFromMdi ( w ) ;
}
bool RemoteMDI : : queryClose ( )
{
// Close all open connections
for ( TQValueList < KMdiChildView * > : : iterator it = m_window . begin ( ) ; it ! = m_window . end ( ) ; + + it ) {
RemoteLab : : InstrumentView * iview = dynamic_cast < RemoteLab : : InstrumentView * > ( * it ) ;
if ( iview ) {
iview - > closeConnections ( ) ;
}
}
// Save current MDI settings (window positions, etc.)
KConfig * c = kapp - > config ( ) ;
// RAJA FIXME
c - > sync ( ) ;
// Allow this window to close
return true ;
}
# include "remotemdi.moc"