You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

284 lines
8.0 KiB

//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(KMdi::MdiMode mode)
: KMdiMainFrm(0, "RemoteMDI", mode), m_children(0)
{
setXMLFile("remotelabui.rc");
// Create some actions
KStdAction::openNew(this, SLOT(openNewWindow()), actionCollection());
KStdAction::close(this, SLOT(closeCurrent()), actionCollection());
KStdAction::quit(this, SLOT(close()), actionCollection());
// Allow the user to change the MDI mode
KToggleAction *tl = new KRadioAction(i18n("Top level mode"), KShortcut(), this, SLOT(switchToToplevelMode()), actionCollection(), "toplevel");
tl->setExclusiveGroup("MDIMode");
tl->setChecked(mode == KMdi::ToplevelMode);
KToggleAction *cf = new KRadioAction(i18n("Child frame mode"), KShortcut(), this, SLOT(switchToChildframeMode()), actionCollection(), "childframe");
cf->setExclusiveGroup("MDIMode");
cf->setChecked(mode == KMdi::ChildframeMode);
KToggleAction *tp = new KRadioAction(i18n("Tab page mode"), KShortcut(), this, SLOT(switchToTabPageMode()), actionCollection(), "tabpage");
tp->setExclusiveGroup("MDIMode");
tp->setChecked(mode == KMdi::TabPageMode);
KToggleAction *id = new KRadioAction( i18n("Ideal mode"), KShortcut(), this, SLOT(switchToIDEAlMode()), actionCollection(), "ideal");
id->setExclusiveGroup("MDIMode");
id->setChecked(mode == KMdi::IDEAlMode);
KToggleAction *inst_sa_menu = new KToggleAction(i18n("Spectrum Analyzer"), KShortcut(), this, SLOT(startSpectrumAnalyzer()), actionCollection(), "spectrum_analyzer");
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);
new KAction(i18n("Launch Spectrum Analyzer"), "remote", CTRL+Key_Home, TQT_TQOBJECT(this), TQT_SLOT(startSpectrumAnalyzer()), ac, "spectrum_analyzer" );
createGUI( 0 );
// When we change view, change the status bar text
connect(this, SIGNAL(viewActivated(KMdiChildView*)), this, SLOT(currentChanged(KMdiChildView*)));
// 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* )));
}
RemoteMDI::~RemoteMDI()
{
while (m_pCurrentWindow) {
closeCurrent();
}
}
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::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 mode
KConfig *c = kapp->config();
// Put in value a matching string value
TQString value;
switch (mdiMode()) {
case KMdi::ToplevelMode:
value = "toplevel";
break;
case KMdi::ChildframeMode:
value = "childframe";
break;
case KMdi::TabPageMode:
value = "tabpage";
break;
case KMdi::IDEAlMode:
value = "ideal";
break;
case KMdi::UndefinedMode:
value = "ideal";
break;
}
// Write it!
c->writeEntry( "MDIMode", value );
c->sync();
// Allow to close the window
return true;
}
#include "remotemdi.moc"