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.

685 lines
23 KiB

/***************************************************************************
kswinworksheet.cpp
-------------------
begin : Thu Jan 17 2002
copyright : (C) 2002 by kamil
email : kamil@localhost.localdomain
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "kswinworksheet.h"
#include "kmatplotshell.h"
#include "kscommands.h"
#include "ksdataobjectfactory.h"
#include "ksglobalmatrixlist.h"
#include "ksobjectfactory.h"
#include "ksmatrixeditor.h"
#include "dialogs/ksimportdlg.h"
#include "dialogs/ksexportdlg.h"
#include "dialogs/ksmpanels.h"
#include "dialogs/kschannellist.h"
#include "widgets/qsdata.h"
#include "pixmaps/action_gray.xpm"
#include "pixmaps/action_green.xpm"
#include <qpixmap.h>
#include <qaction.h>
#include <qfiledialog.h>
#include <qinputdialog.h>
#include <qpopupmenu.h>
//--------------------------------------------------------------------------//
KSWinWorksheet::KSWinWorksheet( KSWorkspace *workspace, bool worksheet_mode )
: KSWorkspaceWindow( workspace, tr("Worksheet"), QPixmap(action_green) )
{
m_shell = workspace->shell();
m_workbook = m_shell->workbook();
m_editor = NULL;
m_data = NULL;
m_curr_data = NULL;
m_curr_channel = -1;
m_removed_data = NULL;
m_worksheet_mode = worksheet_mode;
slot_name_changed( m_curr_data, "" );
}
//--------------------------------------------------------------------------//
KSWinWorksheet::~KSWinWorksheet()
{
}
//--------------------------------------------------------------------------//
void KSWinWorksheet::setDataObject( QSData *data )
{
if ( m_data ) {
disconnect( m_data, SIGNAL(sigDataChanged(QSData*,int)), this, SLOT(slot_data_changed(QSData*,int)) );
disconnect( m_data, SIGNAL(sigChildRemoved(QSData*)), this, SLOT(slot_child_removed(QSData*)) );
disconnect( m_data, SIGNAL(sigDeleted(QSData*)), this, SLOT(slot_deleted(QSData*)) );
disconnect( m_data, SIGNAL(sigNameChanged(QSData*,const char *)), this, SLOT(slot_name_changed(QSData*,const char*)) );
}
if ( m_data && m_data->parentObject() ) {
disconnect( m_data->parentObject(), SIGNAL(sigChildRemoved(QSData*)), this, SLOT(slot_removed(QSData*)) );
}
set_selected( NULL, -1 );
m_data = data;
if ( m_data ) {
connect( m_data, SIGNAL(sigDataChanged(QSData*,int)), this, SLOT(slot_data_changed(QSData*,int)) );
connect( m_data, SIGNAL(sigChildRemoved(QSData*)), this, SLOT(slot_child_removed(QSData*)) );
connect( m_data, SIGNAL(sigDeleted(QSData*)), this, SLOT(slot_deleted(QSData*)) );
connect( m_data, SIGNAL(sigNameChanged(QSData*,const char *)), this, SLOT(slot_name_changed(QSData*,const char*)) );
}
if ( m_data && m_data->parentObject() ) {
connect( m_data->parentObject(), SIGNAL(sigChildRemoved(QSData*)), this, SLOT(slot_removed(QSData*)) );
}
}
//--------------------------------------------------------------------------//
KSChannelList *KSWinWorksheet::chanList() const
{
return dynamic_cast<KSChannelList*>(m_shell->objectContainer()->widget());
}
//--------------------------------------------------------------------------//
KSChannelListItem *KSWinWorksheet::selectedItem() const
{
return chanList() ? chanList()->selected() : NULL;
}
//--------------------------------------------------------------------------//
KSMPanel *KSWinWorksheet::settingsPanel() const
{
return dynamic_cast<KSMPanel*>(m_shell->propertyContainer()->widget());
}
//--------------------------------------------------------------------------//
KSMatrixEditorInterf *KSWinWorksheet::matrixEditor() const
{
return dynamic_cast<KSMatrixEditorInterf*>(contents());
}
//--------------------------------------------------------------------------//
void KSWinWorksheet::activated()
{
m_shell->disableCustomActions();
m_shell->m_new_sheet->setEnabled( TRUE );
m_shell->m_paste->setEnabled( TRUE );
// disable/enable actions
set_selected( m_curr_data, m_curr_channel );
}
//--------------------------------------------------------------------------//
void KSWinWorksheet::deactivated()
{
}
//--------------------------------------------------------------------------//
QWidget *KSWinWorksheet::createObjectPanel( QWidget *parent )
{
KSChannelList *chan_list = new KSChannelList( parent );
chan_list->addColumn( m_worksheet_mode ? tr("Sheets") : tr("Channels"), 85 );
chan_list->addColumn( tr(""), 55 );
chan_list->addColumn( tr(""), 50 );
if ( m_worksheet_mode ) chan_list->setDataObject( m_data, false, 0, false );
else chan_list->setDataObject( m_data, true, -1, true );
if ( m_worksheet_mode ) m_shell->m_paste_sheet->setEnabled( TRUE );
else m_shell->m_paste_sheet->setEnabled( FALSE );
chan_list->select( m_curr_data, m_curr_channel );
connect( chan_list, SIGNAL(selectionChanged()), this, SLOT(slot_channel_selected()) );
connect( chan_list, SIGNAL(sigShowText(const QString&)), m_shell, SLOT(slotShowHelpMessage(const QString&)) );
connect( chan_list, SIGNAL(rightButtonPressed(QListViewItem*,const QPoint&,int)), this, SLOT(slotShowMenu(QListViewItem*,const QPoint&,int)) );
return chan_list;
}
//--------------------------------------------------------------------------//
QWidget *KSWinWorksheet::createPropertyPanel( QWidget *parent )
{
return create_settings_panel();
}
//--------------------------------------------------------------------//
void KSWinWorksheet::make_settings_panel()
{
m_shell->propertyContainer()->setWidget( create_settings_panel() );
}
//--------------------------------------------------------------------//
KSMPanel *KSWinWorksheet::create_settings_panel()
{
KSMPanel *panel = NULL;
if ( m_curr_data && m_curr_channel >= 0 ) {
QSMatrix *matrix = m_curr_data->matrix(m_curr_channel);
if ( matrix ) {
panel = KSDataObjectFactory::createCfgPanel( matrix, m_workbook, m_shell->propertyContainer() );
}
if ( panel ) {
panel->setOrientation( m_shell->bottomDock()->orientation() );
connect( m_shell->bottomDock(), SIGNAL(orientationChanged(Orientation)), panel, SLOT(setOrientation(Orientation)) );
}
}
return panel;
}
//--------------------------------------------------------------------//
void KSWinWorksheet::make_editor()
{
// preserve position
QPoint pos; if ( m_editor ) pos = m_editor->editorContentsPos();
setContents( NULL ); m_editor = NULL;
if ( m_curr_data && m_curr_channel >= 0 ) {
m_editor = KSDataObjectFactory::createEditor( m_workbook, m_curr_data, m_curr_channel, this );
if ( m_editor ) {
m_editor->updateContents();
m_editor->setColumnTitles( KSDataObjectFactory::channelColumnTitlesFactory(m_curr_data,m_curr_channel) );
}
}
setContents( m_editor ? m_editor->widget() : NULL );
// preserve position
if ( m_editor ) m_editor->setEditorContentsPos( pos );
}
//--------------------------------------------------------------------------//
void KSWinWorksheet::set_selected( QSData *dataObject, int channel )
{
if ( m_curr_data != dataObject || m_curr_channel != channel ) {
m_curr_data = dataObject;
m_curr_channel = channel;
if ( chanList() ) chanList()->select( m_curr_data, m_curr_channel );
if ( m_curr_data ) slot_name_changed( m_curr_data, m_curr_data->objectName() );
else slot_name_changed( m_curr_data, "" );
make_settings_panel();
make_editor();
}
if ( m_data ) {
m_shell->m_export_octave->setEnabled( TRUE );
} else {
m_shell->m_export_octave->setEnabled( FALSE );
}
if ( m_curr_data && m_curr_channel >= 0 ) {
m_shell->m_import_octave->setEnabled( TRUE );
m_shell->m_cut->setEnabled( TRUE );
m_shell->m_copy->setEnabled( TRUE );
m_shell->m_copy_all->setEnabled( TRUE );
m_shell->m_delete->setEnabled( TRUE );
m_shell->m_new_matrix->setEnabled( TRUE );
m_shell->m_new_string->setEnabled( TRUE );
m_shell->m_new_formula->setEnabled( TRUE );
m_shell->m_new_reference->setEnabled( TRUE );
m_shell->m_detach->setEnabled( TRUE );
m_shell->m_transpose->setEnabled( TRUE );
} else {
m_shell->m_cut->setEnabled( FALSE );
m_shell->m_copy->setEnabled( FALSE );
m_shell->m_copy_all->setEnabled( FALSE );
m_shell->m_delete->setEnabled( FALSE );
m_shell->m_new_matrix->setEnabled( FALSE );
m_shell->m_new_string->setEnabled( FALSE );
m_shell->m_new_formula->setEnabled( FALSE );
m_shell->m_new_reference->setEnabled( FALSE );
m_shell->m_detach->setEnabled( FALSE );
m_shell->m_transpose->setEnabled( FALSE );
m_shell->m_import_octave->setEnabled( FALSE );
}
if ( dynamic_cast<KSSheet*>(m_curr_data) ) {
m_shell->m_rename_sheet->setEnabled( TRUE );
m_shell->m_raise->setEnabled( TRUE );
m_shell->m_lower->setEnabled( TRUE );
m_shell->m_bring_to_front->setEnabled( TRUE );
m_shell->m_send_to_back->setEnabled( TRUE );
m_shell->m_cut_sheet->setEnabled( TRUE );
m_shell->m_copy_sheet->setEnabled( TRUE );
m_shell->m_copy_all_sheet->setEnabled( TRUE );
m_shell->m_delete_sheet->setEnabled( TRUE );
} else {
m_shell->m_rename_sheet->setEnabled( FALSE );
m_shell->m_raise->setEnabled( FALSE );
m_shell->m_lower->setEnabled( FALSE );
m_shell->m_bring_to_front->setEnabled( FALSE );
m_shell->m_send_to_back->setEnabled( FALSE );
m_shell->m_cut_sheet->setEnabled( FALSE );
m_shell->m_copy_sheet->setEnabled( FALSE );
m_shell->m_copy_all_sheet->setEnabled( FALSE );
m_shell->m_delete_sheet->setEnabled( FALSE );
}
}
//-----------------------------------------------------------//
void KSWinWorksheet::slot_channel_selected()
{
KSChannelListItem *citem = selectedItem();
if ( citem && citem->isValid() ) set_selected( citem->dataObject(), citem->channel() );
else set_selected( NULL, -1 );
}
//--------------------------------------------------------------------//
void KSWinWorksheet::slot_data_changed( QSData *dataObject, int channel )
// data was changed
{
if ( m_curr_data == dataObject && ( m_curr_channel == channel || channel == -1 ) ) {
// recreate settings panel if some bigger changes, update contents otherwise
if ( !settingsPanel() || settingsPanel()->editedMatrix() != dataObject->matrix(channel) )
make_settings_panel();
else settingsPanel()->updateContents();
// recreate editor if some bigger changes, update contents otherwise
if ( !matrixEditor() || matrixEditor()->editedMatrix() != dataObject->matrix(channel) )
make_editor();
else matrixEditor()->updateContents();
}
}
//--------------------------------------------------------------------------//
void KSWinWorksheet::slot_child_removed( QSData *dataObject )
{
if ( dataObject == m_curr_data ) set_selected( NULL, -1 );
}
//--------------------------------------------------------------------------//
void KSWinWorksheet::slot_removed( QSData *dataObject )
// probably user removed our data object from canvas and moved to the undo buffer
{
if ( dataObject == m_data ) {
m_removed_data = m_data;
setDataObject( NULL );
if ( m_removed_data )
connect( m_removed_data, SIGNAL(sigDeleted(QSData*)), this, SLOT(slot_deleted(QSData*)) );
if ( m_removed_data && m_removed_data->parentObject() )
connect( m_removed_data->parentObject(), SIGNAL(sigChildAdded(QSData*)), this, SLOT(slot_added(QSData*)) );
}
}
//--------------------------------------------------------------------------//
void KSWinWorksheet::slot_added( QSData *dataObject )
// probably user called 'undo' and put aoutr object on the canvas again
{
if ( dataObject == m_removed_data ) {
if ( m_removed_data )
disconnect( m_removed_data, SIGNAL(sigDeleted(QSData*)), this, SLOT(slot_deleted(QSData*)) );
if ( m_removed_data && m_removed_data->parentObject() )
disconnect( m_removed_data->parentObject(), SIGNAL(sigChildAdded(QSData*)), this, SLOT(slot_added(QSData*)) );
setDataObject( m_removed_data );
m_removed_data = NULL;
}
}
//--------------------------------------------------------------------------//
void KSWinWorksheet::slot_deleted( QSData * )
{
setDataObject( NULL );
m_removed_data = NULL;
// opss !
delete this;
}
//--------------------------------------------------------------------------//
void KSWinWorksheet::slot_name_changed( QSData *object, const char *name )
{
if ( object == m_curr_data )
setTitle( m_worksheet_mode ? (tr("Worksheet:")+QString(name)) : (tr("Dataset: ")+QString(name)) );
}
//--------------------------------------------------------------------------//
void KSWinWorksheet::doAction( QAction* action )
{
if ( !isActive() ) return;
if ( action == m_shell->m_rename_sheet ) slotRenameSheet();
if ( action == m_shell->m_raise ) slotRaiseSheet();
if ( action == m_shell->m_lower ) slotLowerSheet();
if ( action == m_shell->m_bring_to_front ) slotBringToFrontSheet();
if ( action == m_shell->m_send_to_back ) slotSendToBackSheet();
if ( action == m_shell->m_new_sheet ) slotNewSheet();
if ( action == m_shell->m_import_octave ) slotImportOctave();
if ( action == m_shell->m_export_octave ) slotExportOctave();
if ( action == m_shell->m_new_formula ) slotNewFormula();
if ( action == m_shell->m_new_reference ) slotNewReference();
if ( action == m_shell->m_new_string ) slotNewString();
if ( action == m_shell->m_new_matrix ) slotNewMatrix();
if ( action == m_shell->m_transpose ) slotTranspose();
if ( action == m_shell->m_detach ) slotDetach();
if ( action == m_shell->m_cut_sheet ) slotCutSheet();
if ( action == m_shell->m_copy_sheet ) slotCopySheet();
if ( action == m_shell->m_copy_all_sheet ) slotCopyAllSheet();
if ( action == m_shell->m_paste_sheet ) slotPasteSheet();
if ( action == m_shell->m_delete_sheet ) slotDeleteSheet();
}
//--------------------------------------------------------------------------//
void KSWinWorksheet::cut()
{
KSChannelListItem *item = selectedItem();
if ( item && item->isValid() && item->dataObject()->matrix(item->channel()) ) {
KSObjectFactory factory( m_workbook );
factory.copyQSMatrixToClipboard( item->dataObject()->matrix(item->channel()) );
m_workbook->execute( new KSCmdSetData(item->dataObject(),item->channel(),NULL) );
}
}
//--------------------------------------------------------------------------//
void KSWinWorksheet::copy()
{
KSChannelListItem *item = selectedItem();
if ( item && item->isValid() && item->dataObject()->matrix(item->channel()) ) {
KSObjectFactory factory( m_workbook );
factory.copyQSMatrixToClipboard( item->dataObject()->matrix(item->channel()) );
}
}
//--------------------------------------------------------------------------//
void KSWinWorksheet::copyAll()
{
KSChannelListItem *item = selectedItem();
if ( item && item->isValid() && item->dataObject()->matrix(item->channel()) ) {
KSObjectFactory factory( m_workbook );
factory.setFlags( QSObjectFactory::CopyAllData );
factory.copyQSMatrixToClipboard( item->dataObject()->matrix(item->channel()) );
}
}
//--------------------------------------------------------------------------//
void KSWinWorksheet::paste()
{
KSChannelListItem *item = selectedItem();
if ( item && item->isValid() ) {
KSObjectFactory factory( m_workbook );
QSMatrix *new_matrix = factory.pasteQSMatrixFromClipboard();
if ( new_matrix ) {
m_workbook->execute( new KSCmdSetData(item->dataObject(),item->channel(),new_matrix) );
}
}
}
//--------------------------------------------------------------------------//
void KSWinWorksheet::del()
{
KSChannelListItem *citem = selectedItem();
if ( citem && citem->isValid() ) {
if ( citem->dataObject()->matrix(citem->channel()) ) {
m_workbook->execute( new KSCmdSetData(citem->dataObject(),citem->channel(),NULL) );
} else {
if ( dynamic_cast<KSSheet*>(citem->dataObject()) )
m_workbook->execute(new KSCmdRemoveSheet((KSSheet *)citem->dataObject(),m_workbook->sheets()));
}
}
}
//--------------------------------------------------------------------//
void KSWinWorksheet::slotBringToFrontSheet()
{
KSSheet *selected_sheet = dynamic_cast<KSSheet*>(m_curr_data);
if ( selected_sheet ) {
m_workbook->execute(new KSCmdSheetOrder(KSCmdSheetOrder::ToFront,selected_sheet,m_workbook->sheets()));
}
}
//--------------------------------------------------------------------//
void KSWinWorksheet::slotSendToBackSheet()
{
KSSheet *selected_sheet = dynamic_cast<KSSheet*>(m_curr_data);
if ( selected_sheet ) {
m_workbook->execute(new KSCmdSheetOrder(KSCmdSheetOrder::ToBack,selected_sheet,m_workbook->sheets()));
}
}
//--------------------------------------------------------------------//
void KSWinWorksheet::slotRaiseSheet()
{
KSSheet *selected_sheet = dynamic_cast<KSSheet*>(m_curr_data);
if ( selected_sheet ) {
m_workbook->execute(new KSCmdSheetOrder(KSCmdSheetOrder::Raise,selected_sheet,m_workbook->sheets()));
}
}
//--------------------------------------------------------------------//
void KSWinWorksheet::slotLowerSheet()
{
KSSheet *selected_sheet = dynamic_cast<KSSheet*>(m_curr_data);
if ( selected_sheet ) {
m_workbook->execute(new KSCmdSheetOrder(KSCmdSheetOrder::Lower,selected_sheet,m_workbook->sheets()));
}
}
//-----------------------------------------------------------------------------//
void KSWinWorksheet::slotNewSheet()
{
static int sheet_nr = 1;
KSSheet *new_sheet = new KSSheet( m_workbook->sheets() );
KSMatrixString *new_matrix = new KSMatrixString();
new_matrix->resize(10,10);
new_matrix->setDataObject( new_sheet, 0 );
QCString name;
name.sprintf("sheet%d",sheet_nr++ );
new_matrix->setName( name );
new_sheet->setMatrix( 0, new_matrix );
m_workbook->execute( new KSCmdAddSheet(new_sheet,m_workbook->sheets()) );
}
//-----------------------------------------------------------------------------//
void KSWinWorksheet::slotRenameSheet()
{
KSSheet *selected_sheet = dynamic_cast<KSSheet*>(m_curr_data);
if ( selected_sheet ) {
bool isOK = false;
QString value = QInputDialog::getText( tr( "Rename the sheet" ),
tr( "Enter a new title: " ),
QLineEdit::Normal,
selected_sheet->objectName(),
&isOK,
this );
if ( isOK ) selected_sheet->setObjectName( value );
}
}
//-----------------------------------------------------------------------------//
void KSWinWorksheet::slotDetach()
{
KSChannelListItem *citem = selectedItem();
if ( citem && citem->isValid() ) {
QSMatrix *matrix = citem->dataObject()->matrix(citem->channel());
if ( matrix ) {
KSObjectFactory factory( m_workbook );
QSMatrix *new_matrix = factory.cloneMatrix( matrix, true );
m_workbook->execute( new KSCmdSetData(citem->dataObject(),citem->channel(),new_matrix) );
}
}
}
//-----------------------------------------------------------------------------//
void KSWinWorksheet::slotTranspose()
{
KSChannelListItem *citem = selectedItem();
if ( citem && citem->isValid() ) {
QSMatrix *matrix = citem->dataObject()->matrix(citem->channel());
if ( matrix ) m_workbook->execute( new KSCmdMatrixTranspose(matrix) );
}
}
//-----------------------------------------------------------------------------//
void KSWinWorksheet::slotNewMatrix()
{
KSChannelListItem *citem = selectedItem();
if ( citem && citem->isValid() ) {
m_workbook->execute( new KSCmdSetData(citem->dataObject(),citem->channel(),KSMatrix::create(EDouble)) );
}
}
//-----------------------------------------------------------------------------//
void KSWinWorksheet::slotNewReference()
{
KSChannelListItem *citem = selectedItem();
if ( citem && citem->isValid() ) {
m_workbook->execute( new KSCmdSetData(citem->dataObject(),citem->channel(),new KSMatrixWorksheetCellRange(m_workbook)) );
}
}
//-----------------------------------------------------------------------------//
void KSWinWorksheet::slotNewString()
{
KSChannelListItem *citem = selectedItem();
if ( citem && citem->isValid() ) {
m_workbook->execute( new KSCmdSetData(citem->dataObject(),citem->channel(),new KSMatrixString()) );
}
}
//-----------------------------------------------------------------------------//
void KSWinWorksheet::slotNewFormula()
{
KSChannelListItem *citem = selectedItem();
if ( citem && citem->isValid() ) {
m_workbook->execute( new KSCmdSetData(citem->dataObject(),citem->channel(),new KSMatrixFormula()) );
}
}
//--------------------------------------------------------------------//
void KSWinWorksheet::slotCutSheet()
{
KSSheet *selected_sheet = dynamic_cast<KSSheet*>(m_curr_data);
if ( selected_sheet ) {
KSObjectFactory factory( m_workbook );
factory.copyKSSheetToClipboard(selected_sheet);
m_workbook->execute(new KSCmdRemoveSheet(selected_sheet,m_workbook->sheets()));
}
}
//--------------------------------------------------------------------//
void KSWinWorksheet::slotCopySheet()
{
KSSheet *selected_sheet = dynamic_cast<KSSheet*>(m_curr_data);
if ( selected_sheet ) {
KSObjectFactory factory( m_workbook );
factory.copyKSSheetToClipboard(selected_sheet);
}
}
//--------------------------------------------------------------------//
void KSWinWorksheet::slotCopyAllSheet()
{
KSSheet *selected_sheet = dynamic_cast<KSSheet*>(m_curr_data);
if ( selected_sheet ) {
KSObjectFactory factory( m_workbook );
factory.setFlags( KSObjectFactory::CopyAllData );
factory.copyKSSheetToClipboard(selected_sheet);
}
}
//--------------------------------------------------------------------//
void KSWinWorksheet::slotPasteSheet()
{
KSObjectFactory factory( m_workbook );
KSSheet *new_sheet = factory.pasteKSSheetFromClipboard( m_workbook->sheets() );
if ( new_sheet ) m_workbook->execute(new KSCmdAddSheet(new_sheet,m_workbook->sheets()));
}
//--------------------------------------------------------------------//
void KSWinWorksheet::slotDeleteSheet()
{
KSSheet *selected_sheet = dynamic_cast<KSSheet*>(m_curr_data);
if ( selected_sheet ) {
m_workbook->execute(new KSCmdRemoveSheet(selected_sheet,m_workbook->sheets()));
}
}
//--------------------------------------------------------------------//
void KSWinWorksheet::slotImportOctave()
{
KSImportDlg d( m_workbook, m_curr_data, m_curr_channel );
if ( d.exec() == QFileDialog::Accepted ) d.loadAll();
}
//-----------------------------------------------------------------------------//
void KSWinWorksheet::slotExportOctave()
{
KSExportDlg d( m_data );
if ( d.exec() == QFileDialog::Accepted ) d.saveAll();
}
//-----------------------------------------------------------------------------//
void KSWinWorksheet::slotShowMenu(QListViewItem*, const QPoint& pos, int )
{
if ( !m_worksheet_mode ) return;
QPopupMenu menu;
m_shell->m_rename_sheet->addTo( &menu );
menu.insertSeparator();
m_shell->m_cut_sheet->addTo( &menu );
m_shell->m_copy_sheet->addTo( &menu );
m_shell->m_copy_all_sheet->addTo( &menu );
m_shell->m_paste_sheet->addTo( &menu );
m_shell->m_delete_sheet->addTo( &menu );
menu.insertSeparator();
m_shell->m_raise->addTo( &menu );
m_shell->m_lower->addTo( &menu );
menu.insertSeparator();
m_shell->m_bring_to_front->addTo( &menu );
m_shell->m_send_to_back->addTo( &menu );
menu.exec( pos );
}