diff --git a/src/circuitview.cpp b/src/circuitview.cpp index 75b43e56..bf25906c 100644 --- a/src/circuitview.cpp +++ b/src/circuitview.cpp @@ -1,162 +1,160 @@ /*************************************************************************** * Copyright (C) 2005 by David Saxton * * david@bluehaze.org * * * * 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 "circuitdocument.h" #include "circuitview.h" #include "config.h" #include "ktechlab.h" #include "simulator.h" #include "viewiface.h" #include #include -#include - CircuitView::CircuitView( CircuitDocument * circuitDocument, ViewContainer *viewContainer, uint viewAreaId, const char *name ) : ICNView( circuitDocument, viewContainer, viewAreaId, name ), p_circuitDocument(circuitDocument) { KActionCollection * ac = actionCollection(); { //new KAction( "Dump linear equations", Qt::CTRL|Qt::Key_D, circuitDocument, SLOT(displayEquations()), ac, "dump_les" ); KAction * a = new KAction( i18n("Dump linear equations"), ac); a->setName("dump_les"); a->setShortcut(Qt::CTRL | Qt::Key_D); connect(a, SIGNAL(triggered(bool)), circuitDocument, SLOT(displayEquations())); ac->addAction("dump_les", a); } //BEGIN Item Control Actions KAction * ra; { //ra = new KAction( i18n("0 Degrees"), "", 0, circuitDocument, SLOT(setOrientation0()), ac, "edit_orientation_0" ); // ra->setExclusiveGroup("orientation"); // TODO test KAction *ra = new KAction( KIcon(""), i18n("0 Degrees"), ac); ra->setName("edit_orientation_0"); connect(ra, SIGNAL(triggered(bool)), circuitDocument, SLOT(setOrientation0())); ac->addAction("edit_orientation_0", ra); ra->setChecked(true); } { //ra = new KAction( i18n("90 Degrees"), "", 0, circuitDocument, SLOT(setOrientation90()), ac, "edit_orientation_90" ); // ra->setExclusiveGroup("orientation"); // TODO test KAction *ra = new KAction( KIcon(""), i18n("90 Degrees"), ac); ra->setName("edit_orientation_90"); connect(ra, SIGNAL(triggered(bool)), circuitDocument, SLOT(setOrientation90())); ac->addAction("edit_orientation_90", ra); } { //ra = new KAction( i18n("180 Degrees"), "", 0, circuitDocument, SLOT(setOrientation180()), ac, "edit_orientation_180" ); //ra->setExclusiveGroup("orientation"); // TODO test KAction *ra = new KAction( KIcon(""), i18n("180 Degrees"), ac); ra->setName("edit_orientation_180"); connect(ra, SIGNAL(triggered(bool)), circuitDocument, SLOT(setOrientation180())); ac->addAction("edit_orientation_180", ra); } { //ra =new KAction( i18n("270 Degrees"), "", 0, circuitDocument, SLOT(setOrientation270()), ac, "edit_orientation_270" ); //ra->setExclusiveGroup("orientation"); // TODO test KAction *ra = new KAction( KIcon(""), i18n("270 Degrees"), ac); ra->setName("edit_orientation_270"); connect(ra, SIGNAL(triggered(bool)), circuitDocument, SLOT(setOrientation270())); ac->addAction("edit_orientation_270", ra); } { //new KAction( i18n("Create Subcircuit"), "", 0, circuitDocument, SLOT(createSubcircuit()), ac, "circuit_create_subcircuit" ); KAction *ra = new KAction( KIcon(""), i18n("Create Subcircuit"), ac); ra->setName("circuit_create_subcircuit"); connect(ra, SIGNAL(triggered(bool)), circuitDocument, SLOT(createSubcircuit())); ac->addAction("circuit_create_subcircuit", ra); } { //new KAction( i18n("Rotate Clockwise"), "rotate_cw", "]", circuitDocument, SLOT(rotateClockwise()), ac, "edit_rotate_cw" ); KAction *ra = new KAction( KIcon("rotate_cw"), i18n("Rotate Clockwise"), ac); ra->setName("edit_rotate_cw"); connect(ra, SIGNAL(triggered(bool)), circuitDocument, SLOT(rotateClockwise())); ac->addAction("edit_rotate_cw", ra); } { //new KAction( i18n("Rotate Counter-Clockwise"), "rotate_ccw", "[", circuitDocument, SLOT(rotateCounterClockwise()), ac, "edit_rotate_ccw" ); KAction *ra = new KAction( KIcon("rotate_ccw"), i18n("Rotate Counter-Clockwise"), ac); ra->setName("edit_rotate_ccw"); connect(ra, SIGNAL(triggered(bool)), circuitDocument, SLOT(rotateCounterClockwise())); ac->addAction("edit_rotate_ccw", ra); } { //new KAction( i18n("Flip Horizontally"), "", 0, circuitDocument, SLOT(flipHorizontally()), ac, "edit_flip_horizontally" ); KAction *ra = new KAction( KIcon(""), i18n("Flip Horizontally"), ac); ra->setName("edit_flip_horizontally"); connect(ra, SIGNAL(triggered(bool)), circuitDocument, SLOT(flipHorizontally())); ac->addAction("edit_flip_horizontally", ra); } { //new KAction( i18n("Flip Vertically"), "", 0, circuitDocument, SLOT(flipVertically()), ac, "edit_flip_vertically" ); KAction *ra = new KAction( KIcon(""), i18n("Flip Vertically"), ac); ra->setName("edit_flip_vertically"); connect(ra, SIGNAL(triggered(bool)), circuitDocument, SLOT(flipVertically())); ac->addAction("edit_flip_vertically", ra); } //END Item Control Actions setXMLFile( "ktechlabcircuitui.rc", true ); - QWhatsThis::add( this, i18n( + setWhatsThis( i18n( "Construct a circuit by dragging components from the Component selector from the left. Create the connections by dragging a wire from the component connectors.

" "The simulation is running by default, but can be paused and resumed from the Tools menu.

" "To delete a wire, select it with a select box, and hit delete.

" "To edit the attributes of a component, select it (making sure that no components of another type are also selected), and edit in the toolbar. More advanced properties can be edited using the item editor on the right.

" "Subcircuits can be created by connecting the components with an External Connection, selecting the desired components and clicking on \"Create Subcircuit\" in the right-click menu.") ); m_pViewIface = new CircuitViewIface(this); // note: the text below normally should not be visible; it is needed to get the "real" status displayed; // see slotUpdateRunningStatus m_statusBar->insertItem( i18n("Simulation Initializing"), ViewStatusBar::SimulationState ); connect( Simulator::self(), SIGNAL(simulatingStateChanged(bool )), this, SLOT(slotUpdateRunningStatus(bool )) ); slotUpdateRunningStatus( Simulator::self()->isSimulating() ); } CircuitView::~CircuitView() { delete m_pViewIface; } void CircuitView::slotUpdateRunningStatus( bool isRunning ) { m_statusBar->changeItem( isRunning ? i18n("Simulation Running") : i18n("Simulation Paused"), ViewStatusBar::SimulationState ); } void CircuitView::dragEnterEvent( QDragEnterEvent * e ) { ICNView::dragEnterEvent(e); if ( e->isAccepted() ) return; bool acceptable = e->provides("ktechlab/component") || e->provides("ktechlab/subcircuit"); if ( !acceptable ) return; e->accept( true ); createDragItem( e ); } #include "circuitview.moc" diff --git a/src/flowcodeview.cpp b/src/flowcodeview.cpp index 2bcfac96..a3c337f2 100644 --- a/src/flowcodeview.cpp +++ b/src/flowcodeview.cpp @@ -1,91 +1,89 @@ /*************************************************************************** * Copyright (C) 2005 by David Saxton * * david@bluehaze.org * * * * 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 "flowcodedocument.h" #include "flowcodeview.h" #include "ktechlab.h" #include "viewiface.h" #include #include #include #include #include -#include - FlowCodeView::FlowCodeView( FlowCodeDocument * flowCodeDocument, ViewContainer *viewContainer, uint viewAreaId, const char *name ) : ICNView( flowCodeDocument, viewContainer, viewAreaId, name ) { KActionCollection * ac = actionCollection(); //BEGIN Convert To * Actions //KToolBarPopupAction * pa = new KToolBarPopupAction( i18n("Convert to..."), "fork", 0, 0, 0, ac, "program_convert" ); KToolBarPopupAction * pa = new KToolBarPopupAction( KIcon("fork"), i18n("Convert to..."), ac); pa->setName( "program_convert" ); pa->setDelayed(false); QMenu * m = pa->menu(); m->setTitle( i18n("Convert To") ); m->insertItem( KIcon( "convert_to_microbe" ), i18n("Microbe"), FlowCodeDocument::MicrobeOutput ); m->insertItem( KIcon( "convert_to_assembly" ), i18n("Assembly"), FlowCodeDocument::AssemblyOutput ); m->insertItem( KIcon( "convert_to_hex" ), i18n("Hex"), FlowCodeDocument::HexOutput ); m->insertItem( KIcon( "convert_to_pic" ), i18n("PIC (upload)"), FlowCodeDocument::PICOutput ); connect( m, SIGNAL(activated(int)), flowCodeDocument, SLOT(slotConvertTo(int)) ); ac->addAction("program_convert" , pa); //END Convert To * Actions // new KAction( i18n("Convert to Microbe"), "convert_to_microbe", Qt::Key_F7, flowCodeDocument, SLOT(convertToMicrobe()), ac, "tools_to_microbe" ); // new KAction( i18n("Convert to Assembly"), "convert_to_assembly", Qt::Key_F8, flowCodeDocument, SLOT(convertToAssembly()), ac, "tools_to_assembly" ); // new KAction( i18n("Convert to Hex"), "convert_to_hex", Qt::Key_F9, flowCodeDocument, SLOT(convertToHex()), ac, "tools_to_hex" ); // new KAction( i18n("Upload PIC Program"), "convert_to_pic", 0, flowCodeDocument, SLOT(convertToPIC()), ac, "tools_to_pic" ); setXMLFile( "ktechlabflowcodeui.rc", true ); - QWhatsThis::add( this, i18n( + setWhatsThis( i18n( "Construct a FlowCode document by dragging FlowParts from the list on the left. All FlowCharts require an initial \"Start\" part, of which there can only be one.

" "Some FlowParts, such as Subroutines, act as a container element for other FlowParts. Drag the items in or out of a container as appropriate. The container that will become the parent of the part being dragged is indicated by being selected.

" "Note that connections cannot be made between FlowParts in different containers, or at different levels." ) ); m_pViewIface = new FlowCodeViewIface(this); } FlowCodeView::~FlowCodeView() { delete m_pViewIface; } void FlowCodeView::dragEnterEvent( QDragEnterEvent * e ) { ICNView::dragEnterEvent(e); if ( e->isAccepted() ) return; bool acceptable = e->provides("ktechlab/flowpart"); if ( !acceptable ) return; e->accept( true ); createDragItem( e ); } #include "flowcodeview.moc" diff --git a/src/gui/contexthelp.cpp b/src/gui/contexthelp.cpp index 9938cf30..720cd937 100644 --- a/src/gui/contexthelp.cpp +++ b/src/gui/contexthelp.cpp @@ -1,498 +1,497 @@ /*************************************************************************** * Copyright (C) 2003-2006 by David Saxton * * david@bluehaze.org * * * * 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 "cnitem.h" #include "cnitemgroup.h" #include "contexthelp.h" #include "docmanager.h" #include "itemlibrary.h" #include "itemselector.h" #include "katemdi.h" #include "libraryitem.h" #include "richtexteditor.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include #include #include ContextHelp * ContextHelp::m_pSelf = 0l; ContextHelp * ContextHelp::self( KateMDI::ToolView * parent ) { if (!m_pSelf) { assert(parent); m_pSelf = new ContextHelp(parent); } return m_pSelf; } ContextHelp::ContextHelp( KateMDI::ToolView * parent ) : QWidget(parent), Ui::ContextHelpWidget( /* parent */ ) { setupUi(this); - QWhatsThis::add( this, i18n("Provides context-sensitive help relevant to the current editing being performed.") ); + setWhatsThis( i18n("Provides context-sensitive help relevant to the current editing being performed.") ); setAcceptDrops( true ); if (parent->layout()) { parent->layout()->addWidget(this); qDebug() << Q_FUNC_INFO << " added item selector to parent's layout " << parent; } else { qWarning() << Q_FUNC_INFO << " unexpected null layout on parent " << parent ; } QFont font; font.setBold( true ); if ( font.pointSize() != 0 ) font.setPointSize( int(font.pointSize() * 1.4) ); m_pNameLabel->setFont( font ); m_pNameLabel->setTextFormat( Qt::RichText ); m_pBrowser = new KHTMLPart( m_pWidgetStack->widget( 0 ) ); m_pBrowserView = m_pBrowser->view(); m_pBrowserView->setFocusPolicy( Qt::NoFocus ); m_pBrowserLayout->addWidget( m_pBrowserView ); connect( m_pBrowser->browserExtension(), SIGNAL(openUrlRequest( const KUrl &, const KParts::OpenUrlArguments & ) ), this, SLOT( openURL(const KUrl & /*, const KParts::OpenUrlArguments & */ ) ) ); // Adjust appearance of browser m_pBrowserView->setMarginWidth( 4 ); m_pEditor = new RichTextEditor( m_pWidgetStack->widget( 1 ), "ContextHelpEditor" ); m_pTopLayout->addWidget( m_pEditor ); m_pEditor->installEventFilter( this ); m_pEditor->editorViewport()->installEventFilter( this ); slotClear(); connect( m_pEditButton, SIGNAL(clicked()), this, SLOT(slotEdit()) ); connect( m_pSaveButton, SIGNAL(clicked()), this, SLOT(slotSave()) ); connect( m_pResetButton, SIGNAL(clicked()), this, SLOT(slotEditReset()) ); connect( m_pChangeDescriptionsDirectory, SIGNAL(clicked()), this, SLOT(requestItemDescriptionsDirectory()) ); connect( m_pLanguageSelect, SIGNAL(activated(const QString &)), this, SLOT(setCurrentLanguage( const QString& )) ); m_pResetButton->setPixmap( KIconLoader::global()->loadIcon( "button_cancel", KIconLoader::Small ) ); m_pChangeDescriptionsDirectory->setPixmap( KIconLoader::global()->loadIcon( "folder", KIconLoader::Small ) ); connect( ComponentSelector::self(), SIGNAL(itemSelected( const QString& )), this, SLOT(setBrowserItem( const QString& )) ); connect( FlowPartSelector::self(), SIGNAL(itemSelected( const QString& )), this, SLOT(setBrowserItem( const QString& )) ); #ifdef MECHANICS connect( MechanicsSelector::self(), SIGNAL(itemSelected( const QString& )), this, SLOT(setBrowserItem( const QString& )) ); #endif QTimer::singleShot( 10, this, SLOT(slotInitializeLanguageList()) ); } ContextHelp::~ContextHelp() { } bool ContextHelp::eventFilter( QObject * watched, QEvent * e ) { // kDebug() << k_funcinfo << "watched="<editorViewport()) ) return false; switch ( e->type() ) { case QEvent::DragEnter: { QDragEnterEvent * dragEnter = static_cast(e); if ( !QString( dragEnter->format() ).startsWith("ktechlab/") ) break; dragEnter->acceptAction(); return true; } case QEvent::Drop: { QDropEvent * dropEvent = static_cast(e); if ( !QString( dropEvent->format() ).startsWith("ktechlab/") ) break; dropEvent->accept(); QString type; QDataStream stream( dropEvent->encodedData( dropEvent->format() ) /*, IO_ReadOnly */ ); stream >> type; LibraryItem * li = itemLibrary()->libraryItem( type ); if ( !li ) return true; m_pEditor->insertURL( "ktechlab-help:///" + type, li->name() ); return true; } default: break; } return false; } void ContextHelp::slotInitializeLanguageList() { m_pLanguageSelect->insertStringList( itemLibrary()->descriptionLanguages() ); m_currentLanguage = KGlobal::locale()->language(); m_pLanguageSelect->setCurrentItem( m_currentLanguage ); } bool ContextHelp::isEditChanged() { if ( m_lastItemType.isEmpty() ) return false; // Is the edit widget raised? if ( m_pWidgetStack->visibleWidget() != m_pWidgetStack->widget( 1 ) ) return false; // We are currently editing an item. Is it changed? return ( m_pEditor->text() != itemLibrary()->description( m_lastItemType, m_currentLanguage ).stripWhiteSpace() ); } void ContextHelp::slotUpdate( Item * item ) { if ( isEditChanged() ) return; m_lastItemType = item ? item->type() : QString::null; m_pEditButton->setEnabled( item ); if ( !item ) { slotClear(); return; } m_pWidgetStack->raiseWidget( 0 ); setContextHelp( item->name(), itemLibrary()->description( m_lastItemType, KGlobal::locale()->language() ) ); } void ContextHelp::setBrowserItem( const QString & type ) { if ( isEditChanged() ) return; QString description = itemLibrary()->description( type, KGlobal::locale()->language() ); if ( description.isEmpty() ) return; QString name; LibraryItem * li = itemLibrary()->libraryItem( type ); if ( li ) name = li->name(); else name = type; m_lastItemType = type; setContextHelp( name, description ); m_pEditButton->setEnabled( true ); } void ContextHelp::slotClear() { setContextHelp( i18n("No Item Selected"), 0 ); m_pEditButton->setEnabled( false ); // Can we go hide the edit widget? if ( !isEditChanged() ) m_pWidgetStack->raiseWidget( 0 ); } void ContextHelp::slotMultipleSelected() { setContextHelp( i18n("Multiple Items"), 0 ); } void ContextHelp::setContextHelp( QString name, QString help ) { //BEGIN modify help string as appropriate help = help.stripWhiteSpace(); parseInfo( help ); RichTextEditor::makeUseStandardFont( & help ); addLinkTypeAppearances( & help ); //END modify help string as appropriate // HACK Adjust top spacing according to whether the item description uses

. // This is because the help editor uses paragraphs, but old item help stored // in the items just uses
QFont f; int fontPixelSize = QFontInfo( f ).pixelSize(); if ( help.contains( "

" ) ) m_pBrowserView->setMarginHeight( 3-fontPixelSize ); else m_pBrowserView->setMarginHeight( 3 ); m_pNameLabel->setText( name ); m_pBrowser->begin( itemLibrary()->itemDescriptionsDirectory() ); m_pBrowser->write( help ); m_pBrowser->end(); } void ContextHelp::parseInfo( QString &info ) { info.replace("","

Example:

"); info.replace("","
"); } void ContextHelp::slotEdit() { if ( m_lastItemType.isEmpty() ) return; QStringList resourcePaths; QString currentResourcePath = itemLibrary()->itemDescriptionsDirectory(); QString defaultResourcePath = KStandardDirs::locate( "appdata", "contexthelp/" ); resourcePaths << currentResourcePath; if ( currentResourcePath != defaultResourcePath ) resourcePaths << defaultResourcePath; m_pEditor->setResourcePaths( resourcePaths ); QString description = itemLibrary()->description( m_lastItemType, m_currentLanguage ); m_pEditor->setText( description ); m_pWidgetStack->raiseWidget( 1 ); } void ContextHelp::setCurrentLanguage( const QString & language ) { if ( !saveDescription( m_currentLanguage ) ) { m_pLanguageSelect->blockSignals( true ); m_pLanguageSelect->setCurrentItem( m_currentLanguage ); m_pLanguageSelect->blockSignals( false ); return; } m_currentLanguage = language; slotEdit(); } void ContextHelp::requestItemDescriptionsDirectory() { KDirSelectDialog * dlg = new KDirSelectDialog( itemLibrary()->itemDescriptionsDirectory(), true ); if ( dlg->exec() == QDialog::Accepted ) { itemLibrary()->setItemDescriptionsDirectory( dlg->url().path() ); } delete dlg; return; } void ContextHelp::slotEditReset() { if ( isEditChanged() ) { KGuiItem continueItem = KStandardGuiItem::cont(); //KStandardGuiItem::cont(); continueItem.setText( i18n("Reset") ); int answer = KMessageBox::warningContinueCancel( this, i18n("Reset item help to last saved changes?"), i18n("Reset"), continueItem ); if ( answer == KMessageBox::Cancel ) return; } m_pWidgetStack->raiseWidget( 0 ); } void ContextHelp::slotSave() { if ( !saveDescription( m_currentLanguage ) ) return; setContextHelp( m_pNameLabel->text(), itemLibrary()->description( m_lastItemType, KGlobal::locale()->language() ) ); m_pWidgetStack->raiseWidget( 0 ); } bool ContextHelp::saveDescription( const QString & language ) { if ( m_lastItemType.isEmpty() ) { KMessageBox::sorry( 0, i18n("Cannot save item description.") ); return false; } return itemLibrary()->setDescription( m_lastItemType, m_pEditor->text(), language ); } // static function void ContextHelp::addLinkTypeAppearances( QString * html ) { QRegExp rx("([^<]*)"); int pos = 0; while ( (pos = rx.search( *html, pos )) >= 0 ) { QString anchorText = rx.cap( 0 ); // contains e.g.: KTechlab website QString url = rx.cap( 1 ); // contains e.g.: http://ktechlab.org/ QString text = rx.cap( 2 ); // contains e.g.: KTechlab website int length = anchorText.length(); LinkType lt = extractLinkType( url ); QColor color; // default constructor gives an "invalid" color QString imageURL; switch ( lt ) { case HelpLink: break; case NewHelpLink: color = Qt::red; break; case ExampleLink: { //QString iconName = KMimeType::iconNameForURL( examplePathToFullPath( KUrl( url ).path() ) ); QString iconName = KMimeType::iconNameForUrl( examplePathToFullPath( KUrl( url ).path() ) ); imageURL = KIconLoader::global()->iconPath( iconName, - KIconLoader::SizeSmall ); break; } case ExternalLink: { imageURL = KStandardDirs::locate( "appdata", "icons/external_link.png" ); break; } } QString newAnchorText; if ( color.isValid() ) { newAnchorText = QString("%3").arg( url ).arg( color.name() ).arg( text ); } else if ( !imageURL.isEmpty() ) { newAnchorText = anchorText; newAnchorText += QString(" ").arg( imageURL ); } if ( !newAnchorText.isEmpty() ) html->replace( pos, length, newAnchorText ); pos++; // avoid the string we just found } } // static function ContextHelp::LinkType ContextHelp::extractLinkType( const KUrl & url ) { QString path = url.path(); if ( url.protocol() == "ktechlab-help" ) { if ( itemLibrary()->haveDescription( path, KGlobal::locale()->language() ) ) return HelpLink; else return NewHelpLink; } if ( url.protocol() == "ktechlab-example" ) return ExampleLink; return ExternalLink; } // static function QString ContextHelp::examplePathToFullPath( QString path ) { // quick security check path.remove( ".." ); if ( path.startsWith("/") ) path.remove( 0, 1 ); return KStandardDirs::locate( "appdata", "examples/" + path ); } void ContextHelp::openURL( const KUrl & url /*, const KParts::OpenUrlArguments & */ ) { QString path = url.path(); switch ( extractLinkType( url ) ) { case HelpLink: case NewHelpLink: setBrowserItem( path ); break; case ExampleLink: DocManager::self()->openURL( examplePathToFullPath( path ) ); break; case ExternalLink: { // external url KRun * r = new KRun( url, this ); connect( r, SIGNAL(finished()), r, SLOT(deleteLater()) ); connect( r, SIGNAL(error()), r, SLOT(deleteLater()) ); break; } } } #include "contexthelp.moc" diff --git a/src/gui/itemeditor/itemeditor.cpp b/src/gui/itemeditor/itemeditor.cpp index 69f42c9e..f67a47cc 100644 --- a/src/gui/itemeditor/itemeditor.cpp +++ b/src/gui/itemeditor/itemeditor.cpp @@ -1,150 +1,149 @@ /*************************************************************************** * Copyright (C) 2006 David Saxton * * * * 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 "cnitem.h" #include "cnitemgroup.h" #include "component.h" #include "componentmodelwidget.h" #include "itemeditor.h" #include "orientationwidget.h" #include "propertyeditor.h" #include "katemdi.h" #include #include #include #include #include -#include #include #include ItemEditor * ItemEditor::m_pSelf = 0l; ItemEditor * ItemEditor::self( KateMDI::ToolView * parent ) { if (!m_pSelf) { assert(parent); m_pSelf = new ItemEditor(parent); } return m_pSelf; } ItemEditor::ItemEditor( KateMDI::ToolView * parent ) : QWidget( (QWidget*)parent, "Item Editor" ) { - QWhatsThis::add( this, i18n("This allows editing of advanced properties of the selected item(s). Right click on the picture of the item to set the orientation.") ); + setWhatsThis( i18n("This allows editing of advanced properties of the selected item(s). Right click on the picture of the item to set the orientation.") ); if (parent->layout()) { parent->layout()->addWidget(this); qDebug() << Q_FUNC_INFO << " added item selector to parent's layout " << parent; } else { qWarning() << Q_FUNC_INFO << " unexpected null layout on parent " << parent ; } QVBoxLayout * vlayout = new QVBoxLayout( this, 0, 6 ); //BEGIN Create Name Label m_pNameLabel = new QLabel( this, "" ); m_pNameLabel->setTextFormat( Qt::RichText ); QFont font; font.setBold( true ); if ( font.pointSize() != 0 ) font.setPointSize( int(font.pointSize() * 1.4) ); m_pNameLabel->setFont( font ); //END Create Name Label m_pPropertyEditor = new PropertyEditor(this); - QWhatsThis::add(m_pPropertyEditor,i18n("

Shows properties associated with the currently selected item(s).
Select a property to change its value. If multiple items are selected with different values then the property will appear greyed out, use \"Merge Properties\" to make them the same.
Select \"Defaults\" to set all properties to their default values")); + m_pPropertyEditor->setWhatsThis(i18n("

Shows properties associated with the currently selected item(s).
Select a property to change its value. If multiple items are selected with different values then the property will appear greyed out, use \"Merge Properties\" to make them the same.
Select \"Defaults\" to set all properties to their default values")); m_pComponentModelWidget = new ComponentModelWidget( this ); vlayout->addWidget( m_pNameLabel ); vlayout->addWidget( m_pPropertyEditor, 3 ); vlayout->addWidget( m_pComponentModelWidget, 5 ); // Orientation widget stuff QHBoxLayout *h2Layout = new QHBoxLayout( vlayout, 6 ); h2Layout->addItem( new QSpacerItem( 1, 1 ) ); m_pOrientationWidget = new OrientationWidget(this); h2Layout->addWidget(m_pOrientationWidget); - QWhatsThis::add(m_pOrientationWidget,i18n("Change the orientation of the selected item by selecting the appropriate button")); + m_pOrientationWidget->setWhatsThis(i18n("Change the orientation of the selected item by selecting the appropriate button")); h2Layout->addItem( new QSpacerItem( 1, 1 ) ); slotClear(); } ItemEditor::~ItemEditor() { } void ItemEditor::slotClear() { m_pPropertyEditor->reset( ); m_pComponentModelWidget->reset(); m_pOrientationWidget->slotClear(); updateNameLabel(0l); } void ItemEditor::slotMultipleSelected() { slotClear(); m_pNameLabel->setText( i18n("Multiple Items") ); } void ItemEditor::slotUpdate( ItemGroup * itemGroup ) { if (!itemGroup) { slotClear(); return; } m_pPropertyEditor->create(itemGroup); updateNameLabel(itemGroup->activeItem()); m_pOrientationWidget->slotUpdate( dynamic_cast(itemGroup) ); } void ItemEditor::itemGroupUpdated( ItemGroup * itemGroup ) { m_pPropertyEditor->updateDefaultsButton(); m_pOrientationWidget->slotUpdate( dynamic_cast(itemGroup) ); } void ItemEditor::slotUpdate( Item * item ) { m_pComponentModelWidget->init( dynamic_cast(item) ); } void ItemEditor::updateNameLabel( Item *item ) { if (item) m_pNameLabel->setText( item->name() ); else m_pNameLabel->setText( i18n("No Item Selected") ); } #include "itemeditor.moc" diff --git a/src/gui/itemselector.cpp b/src/gui/itemselector.cpp index 35a91e28..6ae73669 100644 --- a/src/gui/itemselector.cpp +++ b/src/gui/itemselector.cpp @@ -1,413 +1,412 @@ /*************************************************************************** * Copyright (C) 2003-2006 by David Saxton * * david@bluehaze.org * * * * 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 // Temporay fix for pthread.h problem #include "circuitdocument.h" #include "docmanager.h" #include "flowcodedocument.h" #include "itemdocument.h" #include "itemlibrary.h" #include "itemselector.h" #include "libraryitem.h" #include "mechanicsdocument.h" #include "katemdi.h" #include #include #include #include #include #include #include #include -#include #include ILVItem::ILVItem( K3ListView* parent, const QString &id ) : K3ListViewItem( parent, 0 ) { m_id = id; b_isRemovable = false; m_pProjectItem = 0l; } ILVItem::ILVItem( K3ListViewItem* parent, const QString &id ) : K3ListViewItem( parent, 0 ) { m_id = id; b_isRemovable = false; m_pProjectItem = 0l; } ItemSelector::ItemSelector( QWidget *parent, const char *name ) : K3ListView( parent /*, name */ ) { setName(name); qDebug() << Q_FUNC_INFO << " this=" << this; addColumn( i18n( "Component" ) ); setFullWidth(true); setSorting( -1, false ); setRootIsDecorated(true); setDragEnabled(true); setFocusPolicy( Qt::NoFocus ); setSelectionMode( Q3ListView::Single ); // 2015.12.10 - need to allow selection for removing items if (parent->layout()) { parent->layout()->addWidget(this); qDebug() << Q_FUNC_INFO << " added item selector to parent's layout " << parent; } else { qWarning() << Q_FUNC_INFO << " unexpected null layout on parent " << parent ; } setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); // ? // connect( this, SIGNAL(executed(K3ListViewItem*) ), this, SLOT(slotItemExecuted(K3ListViewItem*)) ); connect( this, SIGNAL(clicked(Q3ListViewItem*)), this, SLOT(slotItemClicked(Q3ListViewItem*)) ); connect( this, SIGNAL(doubleClicked(Q3ListViewItem*)), this, SLOT(slotItemDoubleClicked(Q3ListViewItem*)) ); connect( this, SIGNAL(contextMenuRequested(Q3ListViewItem*, const QPoint&, int )), this, SLOT(slotContextMenuRequested(Q3ListViewItem*, const QPoint&, int )) ); connect( this, SIGNAL(selectionChanged(Q3ListViewItem*)), this, SLOT(slotItemSelected( Q3ListViewItem* )) ); } ItemSelector::~ItemSelector() { writeOpenStates(); } void ItemSelector::clear() { m_categories.clear(); K3ListView::clear(); } void ItemSelector::addItem( const QString & caption, const QString & id, const QString & _category, const QPixmap & icon, bool removable ) { ILVItem *parentItem = 0L; QString category = _category; if ( !category.startsWith("/") ) { category.prepend('/'); } do { category.remove(0,1); QString cat; category.replace( "\\/", "|" ); int pos = category.find('/'); if ( pos == -1 ) cat = category; else cat = category.left( pos ); cat.replace( "|", "/" ); if ( m_categories.findIndex(cat) == -1 ) { m_categories.append(cat); if (parentItem) { parentItem = new ILVItem( parentItem, "" ); } else { parentItem = new ILVItem( this, "" ); } parentItem->setOpen( readOpenState(cat) ); parentItem->setExpandable(true); parentItem->setText( 0, cat ); } else { parentItem = (ILVItem*)findItem( cat, 0 ); } category.remove( 0, pos ); } while ( category.contains('/') ); if ( !parentItem ) { kError() << "Unexpected error in finding parent item for category list"<setPixmap( 0, icon ); item->setText( 0, caption ); item->setRemovable(removable); } void ItemSelector::writeOpenStates() { //KConfig *config = kapp->config(); KSharedConfigPtr configPtr = KGlobal::config(); //config->setGroup( name() ); KConfigGroup configGroup = configPtr->group( name() ); const QStringList::iterator end = m_categories.end(); for ( QStringList::iterator it = m_categories.begin(); it != end; ++it ) { Q3ListViewItem *item = findItem( *it, 0 ); if (item) { configGroup.writeEntry( *it+"IsOpen", item->isOpen() ); } } } bool ItemSelector::readOpenState( const QString &id ) { //KConfig *config = kapp->config(); KSharedConfigPtr configPtr = KGlobal::config(); //config->setGroup( name() ); KConfigGroup configGroup = configPtr->group( name() ); return configGroup.readEntry( id+"IsOpen", true ); } void ItemSelector::slotContextMenuRequested( Q3ListViewItem* item, const QPoint& pos, int /*col*/ ) { if ( !item || !(static_cast(item))->isRemovable() ) { return; } Q3PopupMenu *menu = new Q3PopupMenu(this); menu->insertItem( i18n("Remove %1", item->text(0)), this, SLOT(slotRemoveSelectedItem()) //, Qt::Key_Delete // 2015.12.29 - do not specify shortcut key, because it does not work ); menu->popup(pos); } void ItemSelector::slotRemoveSelectedItem() { qDebug() << Q_FUNC_INFO << "removing selected item"; ILVItem *item = dynamic_cast(selectedItem()); if (!item) { qDebug() << Q_FUNC_INFO << "no selected item to remove"; return; } emit itemRemoved( item->key( 0, 0 ) ); ILVItem *parent = dynamic_cast(item->K3ListViewItem::parent()); delete item; // Get rid of the category as well if it has no children if ( parent && !parent->firstChild() ) { m_categories.remove(parent->text(0)); delete parent; } } void ItemSelector::setListCaption( const QString &caption ) { setColumnText( 0, caption ); } void ItemSelector::slotItemSelected( Q3ListViewItem * item ) { if (!item) return; emit itemSelected( item->key( 0, 0 ) ); } void ItemSelector::slotItemClicked( Q3ListViewItem *item ) { if (!item) return; if ( ItemDocument * itemDocument = dynamic_cast(DocManager::self()->getFocusedDocument()) ) itemDocument->slotUnsetRepeatedItemId(); emit itemClicked( item->key( 0, 0 ) ); } void ItemSelector::slotItemDoubleClicked( Q3ListViewItem *item ) { if (!item) return; QString id = item->key( 0, 0 ); if ( Document * doc = DocManager::self()->getFocusedDocument() ) { if ( doc->type() == Document::dt_flowcode && id.startsWith("flow/") ) (static_cast(doc))->slotSetRepeatedItemId(id); else if ( doc->type() == Document::dt_circuit && (id.startsWith("ec/") || id.startsWith("sc/")) ) (static_cast(doc))->slotSetRepeatedItemId(id); else if ( doc->type() == Document::dt_mechanics && id.startsWith("mech/") ) (static_cast(doc))->slotSetRepeatedItemId(id); } emit itemDoubleClicked(id); } Q3DragObject* ItemSelector::dragObject() { const QString id = currentItem()->key(0,0); Q3StoredDrag * d = 0l; if ( id.startsWith("flow/") ) d = new Q3StoredDrag( "ktechlab/flowpart", this ); else if ( id.startsWith("ec/") ) d = new Q3StoredDrag( "ktechlab/component", this ); else if ( id.startsWith("sc/") ) d = new Q3StoredDrag( "ktechlab/subcircuit", this ); else if ( id.startsWith("mech/") ) d = new Q3StoredDrag( "ktechlab/mechanical", this ); if (d) { QByteArray data; QDataStream stream( &data, IO_WriteOnly ); stream << id; d->setEncodedData(data); } else { qWarning() << Q_FUNC_INFO << " null drag returned"; } // A pixmap cursor is often hard to make out // QPixmap *pixmap = const_cast(currentItem()->pixmap(0)); // if (pixmap) d->setPixmap(*pixmap); return d; } //BEGIN class ComponentSelector ComponentSelector * ComponentSelector::m_pSelf = 0l; ComponentSelector * ComponentSelector::self( KateMDI::ToolView * parent ) { if (!m_pSelf) { assert(parent); m_pSelf = new ComponentSelector(parent); } return m_pSelf; } ComponentSelector::ComponentSelector( KateMDI::ToolView * parent ) : ItemSelector( parent, "Component Selector" ) { qDebug() << Q_FUNC_INFO << " creating " << this; - QWhatsThis::add( this, i18n( + setWhatsThis( i18n( "Add components to the circuit diagram by dragging them into the circuit.

" "To add more than one component of the same type, doubleclick on a component, and click repeatedly in the circuit to place the component. Right click to stop placement.

" "Some components (such as subcircuits) can be removed by right clicking on the item and selecting \"Remove\"." ) ); setListCaption( i18n("Component") ); LibraryItemList *items = itemLibrary()->items(); qDebug() << Q_FUNC_INFO << " there are " << items->count() << " items"; const LibraryItemList::iterator end = items->end(); for ( LibraryItemList::iterator it = items->begin(); it != end; ++it ) { if ( (*it)->type() == LibraryItem::lit_component ) addItem( (*it)->name(), (*it)->activeID(), (*it)->category(), (*it)->icon16() ); } } //END class ComponentSelector //BEGIN class FlowPartSelector FlowPartSelector * FlowPartSelector::m_pSelf = 0l; FlowPartSelector * FlowPartSelector::self( KateMDI::ToolView * parent ) { if (!m_pSelf) { assert(parent); m_pSelf = new FlowPartSelector(parent); } return m_pSelf; } FlowPartSelector::FlowPartSelector( KateMDI::ToolView * parent ) : ItemSelector( (QWidget*)parent, "Part Selector" ) { - QWhatsThis::add( this, i18n("Add FlowPart to the FlowCode document by dragging them there.

To add more than one FlowPart of the same type, doubleclick on a FlowPart, and click repeatedly in the FlowChart to place the component. Right click to stop placement.") ); + setWhatsThis( i18n("Add FlowPart to the FlowCode document by dragging them there.

To add more than one FlowPart of the same type, doubleclick on a FlowPart, and click repeatedly in the FlowChart to place the component. Right click to stop placement.") ); setListCaption( i18n("Flow Part") ); LibraryItemList *items = itemLibrary()->items(); const LibraryItemList::iterator end = items->end(); for ( LibraryItemList::iterator it = items->begin(); it != end; ++it ) { if ( (*it)->type() == LibraryItem::lit_flowpart ) addItem( (*it)->name(), (*it)->activeID(), (*it)->category(), (*it)->icon16() ); } } //END class FlowPartSelector //BEGIN class MechanicsSelector MechanicsSelector * MechanicsSelector::m_pSelf = 0l; MechanicsSelector * MechanicsSelector::self( KateMDI::ToolView * parent ) { if (!m_pSelf) { assert(parent); m_pSelf = new MechanicsSelector( (QWidget*)parent ); } return m_pSelf; } MechanicsSelector::MechanicsSelector( QWidget *parent ) : ItemSelector( (QWidget*)parent, "Mechanics Selector" ) { - QWhatsThis::add( this, i18n("Add mechanical parts to the mechanics work area by dragging them there.") ); + setWhatsThis( i18n("Add mechanical parts to the mechanics work area by dragging them there.") ); LibraryItemList *items = itemLibrary()->items(); const LibraryItemList::iterator end = items->end(); for ( LibraryItemList::iterator it = items->begin(); it != end; ++it ) { if ( (*it)->type() == LibraryItem::lit_mechanical ) { addItem( (*it)->name(), (*it)->activeID(), (*it)->category(), (*it)->icon16() ); } } } //END class MechanicsSelector #include "itemselector.moc" diff --git a/src/gui/microselectwidget.cpp b/src/gui/microselectwidget.cpp index 9393e8a1..5bfbc0d3 100644 --- a/src/gui/microselectwidget.cpp +++ b/src/gui/microselectwidget.cpp @@ -1,131 +1,130 @@ /*************************************************************************** * Copyright (C) 2005 by David Saxton * * david@bluehaze.org * * * * 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 "asminfo.h" #include "microinfo.h" #include "microlibrary.h" #include "microselectwidget.h" #include #include #include #include #include #include -#include MicroSelectWidget::MicroSelectWidget( QWidget* parent, const char* name, Qt::WFlags ) : Q3GroupBox( 4, Qt::Horizontal, i18n("Microprocessor"), parent, name ) { m_allowedAsmSet = AsmInfo::AsmSetAll; m_allowedGpsimSupport = m_allowedFlowCodeSupport = m_allowedMicrobeSupport = MicroInfo::AllSupport; if ( !name ) setName( "MicroSelectWidget" ); m_pMicroFamilyLabel = new QLabel( this, "m_pMicroFamilyLabel" ); m_pMicroFamilyLabel->setText( i18n("Family") ); m_pMicroFamily = new KComboBox( false, this ); //, "m_pMicroFamily" ); m_pMicroFamily->setName("m_pMicroFamily"); m_pMicroFamily->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Preferred ); m_pMicroLabel = new QLabel( this, "m_pMicroLabel" ); m_pMicroLabel->setText( i18n("Micro") ); m_pMicro = new KComboBox( false, this ); //, "m_pMicro" ); m_pMicro->setName("m_pMicro"); m_pMicro->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Preferred ); m_pMicro->setEditable( true ); m_pMicro->setAutoCompletion(true); updateFromAllowed(); setMicro("P16F84"); connect( m_pMicroFamily, SIGNAL(activated(const QString & )), this, SLOT(microFamilyChanged(const QString& )) ); } MicroSelectWidget::~MicroSelectWidget() { } void MicroSelectWidget::setAllowedAsmSet( unsigned allowed ) { m_allowedAsmSet = allowed; updateFromAllowed(); } void MicroSelectWidget::setAllowedGpsimSupport( unsigned allowed ) { m_allowedGpsimSupport = allowed; updateFromAllowed(); } void MicroSelectWidget::setAllowedFlowCodeSupport( unsigned allowed ) { m_allowedFlowCodeSupport = allowed; updateFromAllowed(); } void MicroSelectWidget::setAllowedMicrobeSupport( unsigned allowed ) { m_allowedMicrobeSupport = allowed; updateFromAllowed(); } void MicroSelectWidget::updateFromAllowed() { QString oldFamily = m_pMicroFamily->currentText(); m_pMicroFamily->clear(); #define CHECK_ADD(family) if ( (m_allowedAsmSet & AsmInfo::family) && !MicroLibrary::self()->microIDs( AsmInfo::family, m_allowedGpsimSupport, m_allowedFlowCodeSupport, m_allowedMicrobeSupport ).isEmpty() ) m_pMicroFamily->insertItem( AsmInfo::setToString(AsmInfo::family) ); CHECK_ADD(PIC12) CHECK_ADD(PIC14) CHECK_ADD(PIC16); #undef CHECK_ADD if ( m_pMicroFamily->contains(oldFamily) ) m_pMicroFamily->setCurrentText(oldFamily); microFamilyChanged(oldFamily); } void MicroSelectWidget::setMicro( const QString & id ) { MicroInfo * info = MicroLibrary::self()->microInfoWithID(id); if (!info) return; m_pMicro->clear(); m_pMicro->insertStringList( MicroLibrary::self()->microIDs( info->instructionSet()->set() ) ); m_pMicro->setCurrentText(id); m_pMicroFamily->setCurrentText( AsmInfo::setToString( info->instructionSet()->set() ) ); } QString MicroSelectWidget::micro() const { return m_pMicro->currentText(); } void MicroSelectWidget::microFamilyChanged( const QString & family ) { QString oldID = m_pMicro->currentText(); m_pMicro->clear(); m_pMicro->insertStringList( MicroLibrary::self()->microIDs( AsmInfo::stringToSet(family), m_allowedGpsimSupport, m_allowedFlowCodeSupport, m_allowedMicrobeSupport ) ); if ( m_pMicro->contains(oldID) ) m_pMicro->setCurrentText(oldID); } #include "microselectwidget.moc" diff --git a/src/gui/microsettingsdlg.cpp b/src/gui/microsettingsdlg.cpp index 0972bf8d..648e2ae2 100644 --- a/src/gui/microsettingsdlg.cpp +++ b/src/gui/microsettingsdlg.cpp @@ -1,439 +1,438 @@ /*************************************************************************** * Copyright (C) 2003-2005 by David Saxton * * david@bluehaze.org * * * * 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 "microinfo.h" #include "microsettings.h" #include "microsettingsdlg.h" #include "ui_microsettingswidget.h" #include "micropackage.h" #include "ui_newpinmappingwidget.h" #include "pinmapping.h" #include #include #include #include #include #include #include #include #include #include #include #include -#include struct MicroSettingsWidget : public QWidget, Ui::MicroSettingsWidget { MicroSettingsWidget(QWidget *parent) : QWidget(parent) { setupUi(this); } }; struct NewPinMappingWidget : public QWidget, Ui::NewPinMappingWidget { NewPinMappingWidget(QWidget *parent) :QWidget(parent) { setupUi(this); } }; MicroSettingsDlg::MicroSettingsDlg( MicroSettings * microSettings, QWidget *parent, const char *name ) : //KDialog( parent, name, true, i18n("PIC Settings"), KDialog::Ok|KDialog::Apply|KDialog::Cancel, KDialog::Ok, true ) KDialog( parent /*, name, true, i18n("PIC Settings"), KDialog::Ok|KDialog::Apply|KDialog::Cancel, KDialog::Ok, true */ ) { setName(name); setModal(true); setCaption(i18n("PIC Settings")); setButtons(KDialog::Ok | KDialog::Apply | KDialog::Cancel); setDefaultButton(KDialog::Ok); showButtonSeparator(true); m_pMicroSettings = microSettings; m_pNewPinMappingWidget = 0l; m_pNewPinMappingDlg = 0l; m_pWidget = new MicroSettingsWidget(this); - QWhatsThis::add( this, i18n("This dialog allows editing of the initial properties of the PIC") ); - QWhatsThis::add( m_pWidget->portsGroupBox, i18n("Edit the initial value of the ports here. For each binary number, the order from right-to-left is pins 0 through 7.

The \"Type (TRIS)\" edit shows the initial input/output state of the ports; 1 represents an input, and 0 an output.

The \"State (PORT)\" edit shows the initial high/low state of the ports; 1 represents a high, and 0 a low.") ); - QWhatsThis::add( m_pWidget->variables, i18n("Edit the initial value of the variables here.

Note that the value of the variable can only be in the range 0->255. These variables will be initialized before any other code is executed.") ); + setWhatsThis( i18n("This dialog allows editing of the initial properties of the PIC") ); + m_pWidget->portsGroupBox->setWhatsThis( i18n("Edit the initial value of the ports here. For each binary number, the order from right-to-left is pins 0 through 7.

The \"Type (TRIS)\" edit shows the initial input/output state of the ports; 1 represents an input, and 0 an output.

The \"State (PORT)\" edit shows the initial high/low state of the ports; 1 represents a high, and 0 a low.") ); + m_pWidget->variables->setWhatsThis( i18n("Edit the initial value of the variables here.

Note that the value of the variable can only be in the range 0->255. These variables will be initialized before any other code is executed.") ); //BEGIN Initialize initial port settings m_portNames = microSettings->microInfo()->package()->portNames(); m_portTypeEdit.resize( m_portNames.size(), 0 ); m_portStateEdit.resize( m_portNames.size(), 0 ); uint row = 0; QStringList::iterator end = m_portNames.end(); for ( QStringList::iterator it = m_portNames.begin(); it != end; ++it, ++row ) { //BEGIN Get current Type / State text QString portType = QString::number( microSettings->portType(*it), 2 ); QString portState = QString::number( microSettings->portState(*it), 2 ); QString fill; fill.fill( '0', 8-portType.length() ); portType.prepend(fill); fill.fill( '0', 8-portState.length() ); portState.prepend(fill); //END Get current Type / State text Q3GroupBox * groupBox = new Q3GroupBox( *it, m_pWidget->portsGroupBox ); groupBox->setColumnLayout(0, Qt::Vertical ); groupBox->layout()->setSpacing( 6 ); groupBox->layout()->setMargin( 11 ); QGridLayout * groupBoxLayout = new QGridLayout( groupBox->layout() ); groupBoxLayout->setAlignment( Qt::AlignTop ); // TODO: replace this with i18n( "the type", "Type (TRIS register):" ); groupBoxLayout->addWidget( new QLabel( i18n("Type (TRIS register):"), groupBox ), 0, 0 ); groupBoxLayout->addWidget( new QLabel( i18n("State (PORT register):"), groupBox ), 1, 0 ); m_portTypeEdit[row] = new KLineEdit( portType, groupBox ); groupBoxLayout->addWidget( m_portTypeEdit[row], 0, 1 ); m_portStateEdit[row] = new KLineEdit( portState, groupBox ); groupBoxLayout->addWidget( m_portStateEdit[row], 1, 1 ); // (dynamic_cast(m_pWidget->portsGroupBox->layout()))->insertWidget( row, groupBox ); (dynamic_cast(m_pWidget->portsGroupBox->layout()))->addWidget( groupBox ); } //END Initialize initial port settings //BEGIN Initialize initial variable settings // Hide row headers m_pWidget->variables->setLeftMargin(0); // Make columns as thin as possible m_pWidget->variables->setColumnStretchable( 0, true ); m_pWidget->variables->setColumnStretchable( 1, true ); QStringList variables = microSettings->variableNames(); row = 0; end = variables.end(); for ( QStringList::iterator it = variables.begin(); it != end; ++it ) { VariableInfo *info = microSettings->variableInfo(*it); if (info) { m_pWidget->variables->insertRows( row, 1 ); m_pWidget->variables->setText( row, 0, *it ); m_pWidget->variables->setText( row, 1, info->valueAsString() ); ++row; } } m_pWidget->variables->insertRows( row, 1 ); connect( m_pWidget->variables, SIGNAL(valueChanged(int,int)), this, SLOT(checkAddVariableRow()) ); //END Initialize initial variable settings //BEGIN Initialize pin maps connect( m_pWidget->pinMapAdd, SIGNAL(clicked()), this, SLOT(slotCreatePinMap()) ); connect( m_pWidget->pinMapModify, SIGNAL(clicked()), this, SLOT(slotModifyPinMap()) ); connect( m_pWidget->pinMapRename, SIGNAL(clicked()), this, SLOT(slotRenamePinMap()) ); connect( m_pWidget->pinMapRemove, SIGNAL(clicked()), this, SLOT(slotRemovePinMap()) ); m_pinMappings = microSettings->pinMappings(); m_pWidget->pinMapCombo->insertStringList( m_pinMappings.keys() ); updatePinMapButtons(); //END Initialize pin maps //enableButtonSeparator( false ); showButtonSeparator( false ); setMainWidget(m_pWidget); m_pWidget->adjustSize(); adjustSize(); connect( this, SIGNAL(applyClicked()), this, SLOT(slotSaveStuff()) ); } MicroSettingsDlg::~MicroSettingsDlg() { } void MicroSettingsDlg::accept() { hide(); slotSaveStuff(); deleteLater(); } void MicroSettingsDlg::slotSaveStuff() { for ( unsigned i = 0; i < m_portNames.size(); i++ ) savePort(i); m_pMicroSettings->removeAllVariables(); for ( int i=0; i< m_pWidget->variables->numRows(); i++ ) saveVariable(i); m_pMicroSettings->setPinMappings( m_pinMappings ); } void MicroSettingsDlg::reject() { hide(); deleteLater(); } QValidator::State MicroSettingsDlg::validatePinMapName( QString & name ) const { name.replace( ' ', '_' ); if ( name.isEmpty() ) return QValidator::Intermediate; for ( unsigned i = 0; i < name.length(); ++i ) { if ( !name[i].isLetterOrNumber() && name[i] != '_' ) return QValidator::Invalid; } if ( name[0].isNumber() ) return QValidator::Intermediate; if ( m_pWidget->pinMapCombo->contains( name ) ) return QValidator::Intermediate; return QValidator::Acceptable; } void MicroSettingsDlg::slotCheckNewPinMappingName( const QString & name ) { // Validate name might change the name so that it is valid QString newName = name; if ( m_pNewPinMappingWidget ) { m_pNewPinMappingDlg->enableButtonOk( validatePinMapName( newName ) == QValidator::Acceptable ); } if ( newName != name ) m_pNewPinMappingWidget->nameEdit->setText( newName ); } void MicroSettingsDlg::slotCreatePinMap() { //m_pNewPinMappingDlg = new KDialog( this, "New Pin Mapping Dlg", true, i18n("New Pin Mapping"), Ok | Cancel ); m_pNewPinMappingDlg = new KDialog( this); m_pNewPinMappingDlg->setName( "New Pin Mapping Dlg" ); m_pNewPinMappingDlg->setModal( true ); m_pNewPinMappingDlg->setCaption(i18n("New Pin Mapping")); m_pNewPinMappingDlg->setButtons( KDialog::Ok | KDialog::Cancel ); m_pNewPinMappingDlg->setButtonText( Ok, i18n("Create") ); m_pNewPinMappingWidget = new NewPinMappingWidget( m_pNewPinMappingDlg ); m_pNewPinMappingDlg->setMainWidget( m_pNewPinMappingWidget ); PinMappingNameValidator * validator = new PinMappingNameValidator( this ); m_pNewPinMappingWidget->nameEdit->setValidator( validator ); connect( m_pNewPinMappingWidget->nameEdit, SIGNAL(textChanged(const QString &)), this, SLOT(slotCheckNewPinMappingName(const QString &)) ); slotCheckNewPinMappingName( 0 ); int accepted = m_pNewPinMappingDlg->exec(); unsigned selectedType = m_pNewPinMappingWidget->typeCombo->currentItem(); QString name = m_pNewPinMappingWidget->nameEdit->text(); delete m_pNewPinMappingDlg; delete validator; m_pNewPinMappingDlg = 0l; m_pNewPinMappingWidget = 0l; if ( accepted != QDialog::Accepted ) return; PinMapping::Type type = PinMapping::Invalid; switch ( selectedType ) { case 0: type = PinMapping::SevenSegment; break; case 1: type = PinMapping::Keypad_4x3; break; case 2: type = PinMapping::Keypad_4x4; break; default: kError() << k_funcinfo << "Unknown selected type " << type << endl; break; } m_pinMappings[name] = PinMapping( type ); m_pWidget->pinMapCombo->insertItem( name ); //m_pWidget->pinMapCombo->setCurrentItem( m_pWidget->pinMapCombo->count() - 1 ); m_pWidget->pinMapCombo->setCurrentItem( name ); updatePinMapButtons(); slotModifyPinMap(); } void MicroSettingsDlg::slotRenamePinMap() { KComboBox * combo = m_pWidget->pinMapCombo; QString oldName = combo->currentText(); if ( oldName.isEmpty() ) return; PinMappingNameValidator * validator = new PinMappingNameValidator( this, oldName ); bool ok = false; QString newName = KInputDialog::getText( i18n("New Pin Map Name"), i18n("Name"), oldName, & ok, this,/* 0, */ validator ); delete validator; if ( !ok ) return; if ( newName == oldName ) return; m_pinMappings[ newName ] = m_pinMappings[ oldName ]; m_pinMappings.remove( oldName ); combo->setCurrentText( newName ); } void MicroSettingsDlg::slotModifyPinMap() { QString name = m_pWidget->pinMapCombo->currentText(); PinMapping pinMapping = m_pinMappings[ name ]; PinMapEditor * pinMapEditor = new PinMapEditor( & pinMapping, m_pMicroSettings->microInfo(), this, "PinMapEditor" ); int accepted = pinMapEditor->exec(); delete pinMapEditor; if ( accepted != QDialog::Accepted ) return; m_pinMappings[ name ] = pinMapping; } void MicroSettingsDlg::slotRemovePinMap() { KComboBox * combo = m_pWidget->pinMapCombo; QString pinMapID = combo->currentText(); if ( pinMapID.isEmpty() ) return; m_pinMappings.remove( pinMapID ); combo->removeItem( combo->currentItem() ); updatePinMapButtons(); } void MicroSettingsDlg::updatePinMapButtons() { bool havePinMaps = (m_pWidget->pinMapCombo->count() != 0); m_pWidget->pinMapModify->setEnabled( havePinMaps ); m_pWidget->pinMapRename->setEnabled( havePinMaps ); m_pWidget->pinMapRemove->setEnabled( havePinMaps ); } void MicroSettingsDlg::savePort( int row ) { QString port = m_portNames[row]; int type, state; QString typeText = m_portTypeEdit[row]->text(); bool typeOk = true; if ( typeText.startsWith( "0x", false ) ) type = typeText.remove(0,2).toInt( &typeOk, 16 ); else if ( typeText.contains( QRegExp("[^01]") ) ) type = typeText.toInt( &typeOk, 10 ); else type = typeText.toInt( &typeOk, 2 ); if ( !typeOk ) { // KMessageBox::sorry( this, i18n("Unregnised Port Type: %1", typeText) ); return; } QString stateText = m_portStateEdit[row]->text(); bool stateOk = true; if ( stateText.startsWith( "0x", false ) ) state = stateText.remove(0,2).toInt( &stateOk, 16 ); else if ( stateText.contains( QRegExp("[^01]") ) ) state = stateText.toInt( &stateOk, 10 ); else state = stateText.toInt( &stateOk, 2 ); if ( !stateOk ) { // KMessageBox::sorry( this, i18n("Unregnised Port State: %1", stateText) ); return; } m_pMicroSettings->setPortState( port, state ); m_pMicroSettings->setPortType( port, type ); } void MicroSettingsDlg::saveVariable( int row ) { QString name = m_pWidget->variables->text( row, 0 ); if ( name.isEmpty() ) return; QString valueText = m_pWidget->variables->text( row, 1 ); int value; bool ok = true; if ( valueText.startsWith( "0x", false ) ) value = valueText.remove(0,2).toInt( &ok, 16 ); else value = valueText.toInt( &ok, 10 ); if (!ok) { KMessageBox::sorry( this, i18n("Invalid variable value: %1", valueText) ); return; } m_pMicroSettings->setVariable( name, value, true ); VariableInfo *info = m_pMicroSettings->variableInfo(name); if ( info && info->valueAsString().toInt() != value ) { // info->setValue(value); // info->permanent = true; info->initAtStart = true; } } void MicroSettingsDlg::checkAddVariableRow() { int lastRow = m_pWidget->variables->numRows()-1; if ( !m_pWidget->variables->text( lastRow, 0 ).isEmpty() ) m_pWidget->variables->insertRows( lastRow+1, 1 ); } #include "microsettingsdlg.moc" diff --git a/src/ktechlab.cpp b/src/ktechlab.cpp index b19563a5..5195db23 100644 --- a/src/ktechlab.cpp +++ b/src/ktechlab.cpp @@ -1,1495 +1,1494 @@ /*************************************************************************** * Copyright (C) 2003-2005 by David Saxton * * david@bluehaze.org * * * * 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. * ***************************************************************************/ #define protected public #include #undef protected #include "circuitdocument.h" #include "componentmodellibrary.h" #include "config.h" #include "contexthelp.h" #include "docmanager.h" #include "filemetainfo.h" #include "flowcodedocument.h" #include "itemeditor.h" #include "itemgroup.h" #include "iteminterface.h" #include "itemlibrary.h" #include "ktechlab.h" #include "core/ktlconfig.h" #include "languagemanager.h" #include "mechanicsdocument.h" #include "microlibrary.h" #include "newfiledlg.h" #include "oscilloscope.h" #include "projectmanager.h" #include "recentfilesaction.h" #include "scopescreen.h" #include "settingsdlg.h" #include "subcircuits.h" #include "symbolviewer.h" #include "textdocument.h" #include "textview.h" #include "viewcontainer.h" #include #include #include -#include #include #include #include #include #include #include #include #include #include #include //#include #include #include //#include #include #include #include //#include #include #include #include #include #include #include #include #include #include KTechlab * KTechlab::m_pSelf = 0l; KTechlab::KTechlab() : KateMDI::MainWindow( 0, "KTechlab" ) { m_pSelf = this; QTime ct; ct.start(); m_bIsShown = false; m_pContainerDropSource = 0l; m_pContainerDropReceived = 0l; m_pContextMenuContainer = 0l; m_pFocusedContainer = 0l; m_pToolBarOverlayLabel = 0l; if ( QFontInfo( m_itemFont ).pixelSize() > 11 ) { // It has to be > 11, not > 12, as (I think) pixelSize() rounds off the actual size m_itemFont.setPixelSize(12); } m_pUpdateCaptionsTimer = new QTimer( this ); connect( m_pUpdateCaptionsTimer, SIGNAL(timeout()), this, SLOT(slotUpdateCaptions()) ); setMinimumSize( 400, 400 ); setupTabWidget(); setupToolDocks(); setupActions(); setupView(); //readProperties( KGlobal::config() ); KSharedConfigPtr cfg = KGlobal::config(); readPropertiesInConfig( cfg.data() ); // kDebug() << "Constructor time: " << ct.elapsed() << endl; } KTechlab::~KTechlab() { fileMetaInfo()->saveAllMetaInfo(); for (ViewContainerList::Iterator itVc = m_viewContainerList.begin(); itVc != m_viewContainerList.end(); ++itVc ) { ViewContainer *vc = itVc->data(); disconnect( vc, SIGNAL(destroyed(QObject* )), this, SLOT(slotViewContainerDestroyed(QObject* )) ); } delete fileMetaInfo(); delete itemLibrary(); // This better be the last time the item library is used! delete subcircuits(); } void KTechlab::show() { KateMDI::MainWindow::show(); m_bIsShown = true; } void KTechlab::openFile( ViewArea * viewArea ) { KUrl::List files = getFileURLs( false ); if ( files.isEmpty() ) return; load( files.first(), viewArea ); } void KTechlab::load( const KUrl & url, ViewArea * viewArea ) { if ( !url.isValid() ) return; if ( url.url().endsWith( ".ktechlab", false ) ) { // This is a ktechlab project; it has to be handled separetly from a // normal file. ProjectManager::self()->slotOpenProject( url ); return; } QString target; // the below code is what you should normally do. in this // example case, we want the url to our own. you probably // want to use this code instead for your app // download the contents if ( !KIO::NetAccess::download( url, target, this ) ) { // If the file could not be downloaded, for example does not // exist on disk, NetAccess will tell us what error to use KMessageBox::error(this, KIO::NetAccess::lastErrorString()); return; } addRecentFile( url ); // set our caption setCaption( url.prettyUrl() ); // load in the file (target is always local) DocManager::self()->openURL( target, viewArea ); // and remove the temp file KIO::NetAccess::removeTempFile( target ); } QStringList KTechlab::recentFiles() { return m_recentFiles->items(); } void KTechlab::setupToolDocks() { #if defined(KDE_MAKE_VERSION) # if KDE_VERSION >= KDE_MAKE_VERSION(3,3,0) setToolViewStyle( KMultiTabBar::KDEV3ICON ); # endif #endif QPixmap pm; KIconLoader * loader = KIconLoader::global(); KateMDI::ToolView * tv = 0l; tv = createToolView( ProjectManager::toolViewIdentifier(), KMultiTabBar::Left, loader->loadIcon( "attach", KIconLoader::Small ), i18n("Project") ); tv->setName("ProjectManager-ToolView"); ProjectManager::self( tv ); pm.load( KStandardDirs::locate( "appdata", "icons/circuit.png" ) ); tv = createToolView( ComponentSelector::toolViewIdentifier(), KMultiTabBar::Left, pm, i18n("Components") ); tv->setName("ComponentSelector-ToolView"); ComponentSelector::self(tv); // Create an instance of the subcircuits interface, now that we have created the component selector subcircuits(); Subcircuits::loadSubcircuits(); pm.load( KStandardDirs::locate( "appdata", "icons/flowcode.png" ) ); tv = createToolView( FlowPartSelector::toolViewIdentifier(), KMultiTabBar::Left, pm, i18n("Flow Parts") ); tv->setName("FlowPartSelector-ToolView"); FlowPartSelector::self(tv); #ifdef MECHANICS pm.load( KStandardDirs::locate( "appdata", "icons/mechanics.png" ) ); tv = createToolView( MechanicsSelector::toolViewIdentifier(), KMultiTabBar::Left, pm, i18n("Mechanics") ); tv->setName("MechanicsSelector-ToolView"); MechanicsSelector::self(tv); #endif pm.load( KStandardDirs::locate( "appdata", "icons/item.png" ) ); tv = createToolView( ItemEditor::toolViewIdentifier(), KMultiTabBar::Right, pm, i18n("Item Editor") ); tv->setName("ItemEditor-ToolView"); ItemEditor::self(tv); tv = createToolView( ContextHelp::toolViewIdentifier(), KMultiTabBar::Right, loader->loadIcon( "contents", KIconLoader::Small ), i18n("Context Help") ); tv->setName("ContextHelp-ToolView"); ContextHelp::self(tv); tv = createToolView( LanguageManager::toolViewIdentifier(), KMultiTabBar::Bottom, loader->loadIcon( "log", KIconLoader::Small ), i18n("Messages") ); tv->setName("LanguageManager-ToolView"); LanguageManager::self( tv ); #ifndef NO_GPSIM tv = createToolView( SymbolViewer::toolViewIdentifier(), KMultiTabBar::Right, loader->loadIcon( "blockdevice", KIconLoader::Small ), i18n("Symbol Viewer") ); tv->setName("SymbolViewer-ToolView"); SymbolViewer::self(tv); #endif addOscilloscopeAsToolView(this); #if 1 //pm.load( locate( "appdata", "icons/oscilloscope.png" ) ); tv = createToolView( ScopeScreen::toolViewIdentifier(), KMultiTabBar::Bottom, loader->loadIcon( "oscilloscope", KIconLoader::Small ), i18n("Scope Screen (Very Rough)") ); tv->setName("ScopeScreen-ToolView"); ScopeScreen::self( tv ); #endif updateSidebarMinimumSizes(); } void KTechlab::addWindow( ViewContainer * vc ) { if ( vc && !m_viewContainerList.contains(vc) ) { m_viewContainerList << vc; connect( vc, SIGNAL(destroyed(QObject* )), this, SLOT(slotViewContainerDestroyed(QObject* )) ); } m_viewContainerList.remove((ViewContainer*)0); slotUpdateTabWidget(); slotDocModifiedChanged(); } void KTechlab::setupView() { setAcceptDrops(true); setStandardToolBarMenuEnabled(true); setXMLFile("ktechlabui.rc"); createShellGUI(true); //action("newfile_popup")->plug( toolBar("mainToolBar"), 0 ); actionByName("newfile_popup")->addTo( toolBar("mainToolBar") ); //action("file_new")->unplug( toolBar("mainToolBar") ); actionByName("file_new")->removeFrom( toolBar("mainToolBar") ); setupExampleActions(); statusBar()->show(); } void KTechlab::overlayToolBarScreenshot() { return; if ( !m_pToolBarOverlayLabel ) { m_pToolBarOverlayLabel = new QLabel( 0, 0, Qt::WStyle_StaysOnTop | Qt::WStyle_Customize | Qt::WStyle_NoBorder | Qt::WNoAutoErase | Qt::WType_Popup ); m_pToolBarOverlayLabel->hide(); m_pToolBarOverlayLabel->setBackgroundMode( Qt::NoBackground ); } if ( !m_bIsShown ) { // The window isn't visible yet, so there's nothing to overlay (and if we tried, // it would appear as a strange floating toolbar). return; } if ( m_pToolBarOverlayLabel->isShown() ) { // This is to avoid successive calls to removeGUIClient when we have // already popped it up for the first call, and don't want to take // another screenshot (as that would be without the toolbar). return; } //QPtrListIterator toolBarIterator(); // unused? // QWidget * toolsWidget = toolBar( "toolsToolBar" ); // QWidget * debugWidget = toolBar( "debugTB" ); KToolBar * toolsWidget = static_cast(child( "toolsToolBar", "KToolBar" )); KToolBar * debugWidget = static_cast(child( "debugTB", "KToolBar" )); if ( !toolsWidget && !debugWidget ) return; QWidget * parent = static_cast(toolsWidget ? toolsWidget->parent() : debugWidget->parent()); QRect grabRect; // 128 is a sanity check (widget can do strange things when being destroyed) if ( toolsWidget && toolsWidget->height() <= 128 ) grabRect |= toolsWidget->geometry(); if ( debugWidget && debugWidget->height() <= 128 ) grabRect |= debugWidget->geometry(); if ( !grabRect.isValid() ) return; QPixmap shot = QPixmap::grabWidget( parent, grabRect.x(), grabRect.y(), grabRect.width(), grabRect.height() ); m_pToolBarOverlayLabel->move( parent->mapToGlobal( grabRect.topLeft() ) ); m_pToolBarOverlayLabel->setFixedSize( grabRect.size() ); m_pToolBarOverlayLabel->setPixmap( shot ); m_pToolBarOverlayLabel->show(); QTimer::singleShot( 100, this, SLOT( hideToolBarOverlay() ) ); } void KTechlab::hideToolBarOverlay() { if ( !m_pToolBarOverlayLabel ) return; // QWidget * hiddenWidget = toolBar( "toolsToolBar" ); // if ( !hiddenWidget ) // return; // hiddenWidget->setBackgroundMode( NoBackground ); // hiddenWidget->setWFlags( WNoAutoErase ); // hiddenWidget->setUpdatesEnabled( false ); m_pToolBarOverlayLabel->hide(); } void KTechlab::addNoRemoveGUIClient( KXMLGUIClient * client ) { if ( client && !m_noRemoveGUIClients.contains( client ) ) m_noRemoveGUIClients << client; } void KTechlab::removeGUIClients() { QList clientsToRemove; QList clients = factory()->clients(); //for ( KXMLGUIClient * client = clients.first(); client; client = clients.next() ) for ( QList::iterator itClient = clients.begin(); itClient != clients.end(); ++itClient) { //if ( client && client != this && !m_noRemoveGUIClients.contains( client ) ) if ( (*itClient != this) && (!m_noRemoveGUIClients.contains( *itClient )) ) clientsToRemove << *itClient; } if ( clients.isEmpty() ) return; overlayToolBarScreenshot(); QList::iterator end = clientsToRemove.end(); for ( QList::iterator it = clientsToRemove.begin(); it != end; ++it ) factory()->removeClient(*it); } void KTechlab::setupTabWidget() { m_pViewContainerTabWidget = new KTabWidget(centralWidget()); if (centralWidget()->layout()) { centralWidget()->layout()->addWidget(m_pViewContainerTabWidget); } else { qWarning() << " unexpected null layout for " << centralWidget(); } connect( tabWidget(), SIGNAL(currentChanged(QWidget* )), this, SLOT(slotViewContainerActivated(QWidget* )) ); //KConfig *config = kapp->config(); //config->setGroup("UI"); KSharedConfigPtr cfg = KGlobal::config(); KConfigGroup grUi = cfg->group("UI"); bool CloseOnHover = grUi.readEntry( "CloseOnHover", false ); tabWidget()->setHoverCloseButton( CloseOnHover ); bool CloseOnHoverDelay = grUi.readEntry( "CloseOnHoverDelay", false ); tabWidget()->setHoverCloseButtonDelayed( CloseOnHoverDelay ); if (grUi.readEntry( "ShowCloseTabsButton", true )) { QToolButton *but = new QToolButton(tabWidget()); but->setIconSet(SmallIcon("tab-close")); but->adjustSize(); but->hide(); connect( but, SIGNAL(clicked()), this, SLOT(slotViewContainerClose()) ); tabWidget()->setCornerWidget(but, Qt::TopRight); } connect(tabWidget(), SIGNAL(contextMenu(QWidget*,const QPoint &)), this, SLOT(slotTabContext(QWidget*,const QPoint &))); } void KTechlab::slotUpdateTabWidget() { m_viewContainerList.remove( (ViewContainer*)0 ); bool noWindows = m_viewContainerList.isEmpty(); if ( QWidget * button = tabWidget()->cornerWidget(Qt::TopRight) ) button->setHidden( noWindows ); if ( noWindows ) setCaption( 0 ); } void KTechlab::setupActions() { KActionCollection *ac = actionCollection(); KStandardAction::openNew( this, SLOT(slotFileNew()), ac ); KStandardAction::open( this, SLOT(slotFileOpen()), ac ); KStandardAction::save( this, SLOT(slotFileSave()), ac ); KStandardAction::saveAs( this, SLOT(slotFileSaveAs()), ac ); KStandardAction::close( this, SLOT(slotViewClose()), ac ); KStandardAction::print( this, SLOT(slotFilePrint()), ac ); KStandardAction::quit( this, SLOT(slotFileQuit()), ac ); KStandardAction::undo( this, SLOT(slotEditUndo()), ac ); KStandardAction::redo( this, SLOT(slotEditRedo()), ac ); KStandardAction::cut( this, SLOT(slotEditCut()), ac ); KStandardAction::copy( this, SLOT(slotEditCopy()), ac ); KStandardAction::paste( this, SLOT(slotEditPaste()), ac ); KStandardAction::keyBindings( this, SLOT(slotOptionsConfigureKeys()), ac ); KStandardAction::configureToolbars( this, SLOT(slotOptionsConfigureToolbars()), ac ); KStandardAction::preferences( this, SLOT(slotOptionsPreferences()), ac ); //BEGIN New file popup //KToolBarPopupAction *p = new KToolBarPopupAction( i18n("&New"), "filenew", // KStandardShortcut::shortcut(KStandardShortcut::New), this, SLOT(slotFileNew()), ac, "newfile_popup" ); KToolBarPopupAction *p = new KToolBarPopupAction( KIcon("document-new"), i18n("&New"), ac); p->setName("newfile_popup"); p->setShortcut( KStandardShortcut::shortcut(KStandardShortcut::New) ); connect(p, SIGNAL(triggered(bool)), this, SLOT(slotFileNew())); ac->addAction("newfile_popup", p); p->menu()->setTitle( i18n("New File") ); { //(new KAction( i18n("Assembly"), "source", 0, this, SLOT(slotFileNewAssembly()), ac, "newfile_asm" ))->plug( p->menu() ); KAction *a = new KAction( KIcon("source"), i18n("Assembly"), ac); a->setName("newfile_asm"); connect(a, SIGNAL(triggered(bool)), this, SLOT(slotFileNewAssembly())); p->menu()->addAction(a); ac->addAction("newfile_asm", a); } { //(new KAction( i18n("C source"), "source_c", 0, this, SLOT(slotFileNewC()), ac, "newfile_c" ))->plug( p->menu() ); KAction *a = new KAction( KIcon("source_c"), i18n("C source"), ac); a->setName("newfile_c"); connect(a, SIGNAL(triggered(bool)), this, SLOT(slotFileNewC())); p->menu()->addAction(a); ac->addAction("newfile_c", a); } { //(new KAction( i18n("Circuit"), "ktechlab_circuit", 0, this, SLOT(slotFileNewCircuit()), ac, "newfile_circuit" ))->plug( p->menu() ); KAction *a = new KAction( KIcon("ktechlab_circuit"), i18n("Circuit"), ac); a->setName("newfile_circuit"); connect(a, SIGNAL(triggered(bool)), this, SLOT(slotFileNewCircuit())); p->menu()->addAction(a); ac->addAction("newfile_circuit", a); } { //(new KAction( i18n("FlowCode"), "ktechlab_flowcode", 0, this, SLOT(slotFileNewFlowCode()), ac, "newfile_flowcode" ))->plug( p->menu() ); KAction *a = new KAction( KIcon("ktechlab_flowcode"), i18n("FlowCode"), ac); a->setName("newfile_flowcode"); connect(a, SIGNAL(triggered(bool)), this, SLOT(slotFileNewFlowCode())); p->menu()->addAction(a); ac->addAction("newfile_flowcode", a); } #ifdef MECHANICS { //(new KAction( i18n("Mechanics"), "ktechlab_mechanics", 0, this, SLOT(slotFileNewMechanics()), ac, "newfile_mechanics" ))->plug( p->menu() ); KAction *a = new KAction( KIcon("" /* "ktechlab_mechanics" -- for the future */), i18n("Mechanics"), ac); a->setName("newfile_mechanics"); connect(a, SIGNAL(triggered(bool)), this, SLOT(slotFileNewMechanics())); p->menu()->addAction(a); ac->addAction("newfile_mechanics", a); } #endif { //(new KAction( "Microbe", "ktechlab_microbe", 0, this, SLOT(slotFileNewMicrobe()), ac, "newfile_microbe" ))->plug( p->menu() ); KAction *a = new KAction( KIcon("ktechlab_microbe"), i18n("Microbe"), ac); a->setName("newfile_microbe"); connect(a, SIGNAL(triggered(bool)), this, SLOT(slotFileNewMicrobe())); p->menu()->addAction(a); ac->addAction("newfile_microbe", a); } //END New File popup // m_recentFiles = KStandardAction::openRecent( this, SLOT(load(const KUrl&)), ac ); m_recentFiles = new RecentFilesAction( "Recent Files", i18n("Open Recent"), this, SLOT(load(const KUrl &)), ac, "file_open_recent" ); ac->addAction(m_recentFiles->name(), m_recentFiles); m_statusbarAction = KStandardAction::showStatusbar( this, SLOT(slotOptionsShowStatusbar()), ac ); ac->addAction("view_show_status_bar", m_statusbarAction); //BEGIN Project Actions ProjectManager *pm = ProjectManager::self(); { //new KAction( i18n("New Project..."), "window_new", 0, pm, SLOT(slotNewProject()), ac, "project_new" ); KAction *a = new KAction( KIcon("window_new"), i18n("New Project..."), ac); a->setName("project_new"); connect(a, SIGNAL(triggered(bool)), pm, SLOT(slotNewProject())); ac->addAction("project_new", a); } { //new KAction( i18n("Open Project..."), "project_open", 0, pm, SLOT(slotOpenProject()), ac, "project_open" ); KAction *a = new KAction( KIcon("project_open"), i18n("Open Project..."), ac); a->setName("project_open"); connect(a, SIGNAL(triggered(bool)), pm, SLOT(slotOpenProject())); ac->addAction("project_open", a); } { // m_recentProjects = new KRecentFilesAction( i18n("Open &Recent Project..."), 0, ProjectManager::self(), SLOT(slotOpenProject(const KUrl&)), ac, "project_open_recent" ); m_recentProjects = new RecentFilesAction( "Recent Projects", i18n("Open &Recent Project..."), ProjectManager::self(), SLOT(slotOpenProject(const KUrl&)), ac, "project_open_recent" ); ac->addAction("project_open_recent", m_recentProjects); } { //new KAction( i18n("Export to Makefile..."), "fileexport", 0, pm, SLOT(slotExportToMakefile()), ac, "project_export_makefile" ); KAction *a = new KAction( KIcon("fileexport"), i18n("Export to Makefile..."), ac); a->setName("project_export_makefile"); connect(a, SIGNAL(triggered(bool)), pm, SLOT(slotExportToMakefile())); ac->addAction("project_export_makefile", a); } { //new KAction( i18n("Create Subproject..."), 0, 0, pm, SLOT(slotCreateSubproject()), ac, "project_create_subproject" ); KAction *a = new KAction( KIcon(""), i18n("Create Subproject..."), ac); a->setName("project_create_subproject"); connect(a, SIGNAL(triggered(bool)), pm, SLOT(slotCreateSubproject())); ac->addAction("project_create_subproject", a); } { //new KAction( i18n("Add Existing File..."), "fileopen", 0, pm, SLOT(slotAddFile()), ac, "project_add_existing_file" ); KAction *a = new KAction( KIcon("fileopen"), i18n("Add Existing File..."), ac); a->setName("project_add_existing_file"); connect(a, SIGNAL(triggered(bool)), pm, SLOT(slotAddFile())); ac->addAction("project_add_existing_file", a); } { //new KAction( i18n("Add Current File..."), "fileimport", 0, pm, SLOT(slotAddCurrentFile()), ac, "project_add_current_file" ); KAction *a = new KAction( KIcon("document-import"), i18n("Add Current File..."), ac); a->setName("project_add_current_file"); connect(a, SIGNAL(triggered(bool)), pm, SLOT(slotAddCurrentFile())); ac->addAction("project_add_current_file", a); } // new KAction( i18n("Project Options"), "configure", 0, pm, SLOT(slotProjectOptions()), ac, "project_options" ); // ^ TODO why commented? { //new KAction( i18n("Close Project"), "fileclose", 0, pm, SLOT(slotCloseProject()), ac, "project_close" ); KAction *a = new KAction( KIcon("fileclose"), i18n("Close Project"), ac); a->setName("project_close"); connect(a, SIGNAL(triggered(bool)), pm, SLOT(slotCloseProject())); ac->addAction("project_close", a); } { //new KAction( i18n("Remove from Project"), "editdelete", 0, pm, SLOT(slotRemoveSelected()), ac, "project_remove_selected" ); KAction *a = new KAction( KIcon("editdelete"), i18n("Remove from Project"), ac); a->setName("project_remove_selected"); connect(a, SIGNAL(triggered(bool)), pm, SLOT(slotRemoveSelected())); ac->addAction("project_remove_selected", a); } { //new KAction( i18n("Insert Existing File..."), "fileopen", 0, pm, SLOT(slotSubprojectAddExistingFile()), ac, "subproject_add_existing_file" ); KAction *a = new KAction( KIcon("fileopen"), i18n("Insert Existing File..."), ac); a->setName("subproject_add_existing_file"); connect(a, SIGNAL(triggered(bool)), pm, SLOT(slotSubprojectAddExistingFile())); ac->addAction("subproject_add_existing_file", a); } { //new KAction( i18n("Insert Current File..."), "fileimport", 0, pm, SLOT(slotSubprojectAddCurrentFile()),ac, "subproject_add_current_file" ); KAction *a = new KAction( KIcon("document-import"), i18n("Insert Current File..."), ac); a->setName("subproject_add_current_file"); connect(a, SIGNAL(triggered(bool)), pm, SLOT(slotSubprojectAddCurrentFile())); ac->addAction("subproject_add_current_file", a); } { //new KAction( i18n("Linker Options..."), "configure", 0, pm, SLOT(slotSubprojectLinkerOptions()), ac, "project_item_linker_options" ); KAction *a = new KAction( KIcon("configure"), i18n("Linker Options..."), ac); a->setName("project_item_linker_options"); connect(a, SIGNAL(triggered(bool)), pm, SLOT(slotSubprojectLinkerOptions())); ac->addAction("project_item_linker_options", a); } { //new KAction( i18n("Build..."), "launch", 0, pm, SLOT(slotItemBuild()), ac, "project_item_build" ); KAction *a = new KAction( KIcon("run-build"), i18n("Build..."), ac); a->setName("project_item_build"); connect(a, SIGNAL(triggered(bool)), pm, SLOT(slotItemBuild())); ac->addAction("project_item_build", a); } { //new KAction( i18n("Upload..."), "convert_to_pic", 0, pm, SLOT(slotItemUpload()), ac, "project_item_upload" ); KAction *a = new KAction( KIcon("convert_to_pic"), i18n("Upload..."), ac); a->setName("project_item_upload"); connect(a, SIGNAL(triggered(bool)), pm, SLOT(slotItemUpload())); ac->addAction("project_item_upload", a); } { //new KAction( i18n("Processing Options..."), "configure", 0, pm, SLOT(slotItemProcessingOptions()), ac, "project_item_processing_options" ); KAction *a = new KAction( KIcon("configure"), i18n("Processing Options..."), ac); a->setName("project_item_processing_options"); connect(a, SIGNAL(triggered(bool)), pm, SLOT(slotItemProcessingOptions())); ac->addAction("project_item_processing_options", a); } //END Project Actions { //new KAction( i18n("Split View Left/Right"), "view_right", Qt::CTRL|Qt::SHIFT|Qt::Key_L, this, SLOT(slotViewSplitLeftRight()), ac, "view_split_leftright" ); KAction *a = new KAction( KIcon("view_right"), i18n("Split View Left/Right"), ac); a->setName("view_split_leftright"); connect(a, SIGNAL(triggered(bool)), this, SLOT(slotViewSplitLeftRight())); ac->addAction("view_split_leftright", a); } { //new KAction( i18n("Split View Top/Bottom"), "view_bottom", Qt::CTRL|Qt::SHIFT|Qt::Key_T, this, SLOT(slotViewSplitTopBottom()), ac, "view_split_topbottom" ); KAction *a = new KAction( KIcon("view_bottom"), i18n("Split View Top/Bottom"), ac); a->setName("view_split_topbottom"); connect(a, SIGNAL(triggered(bool)), this, SLOT(slotViewSplitTopBottom())); ac->addAction("view_split_topbottom", a); } { //KToggleAction * ta = new KToggleAction( i18n("Run Simulation"), "player_play", Qt::Key_F10, 0, 0, ac, "simulation_run" ); KToggleAction * ta = new KToggleAction( KIcon("player_play"), i18n("Run Simulation"), ac); ta->setShortcut( Qt::Key_F10 ); ta->setName( "simulation_run" ); ta->setChecked(true); connect( ta, SIGNAL(toggled(bool )), Simulator::self(), SLOT(slotSetSimulating(bool )) ); #if defined(KDE_MAKE_VERSION) # if KDE_VERSION >= KDE_MAKE_VERSION(3,3,0) ta->setCheckedState( KGuiItem( i18n("Pause Simulation"), "player_pause", 0 ) ); # endif #endif ac->addAction( "simulation_run", ta); } // We can call slotCloseProject now that the actions have been created ProjectManager::self()->updateActions(); DocManager::self()->disableContextActions(); } void KTechlab::setupExampleActions() { QStringList categories; categories << "555" << "basic" << "diodes" << "jfets" << "opamps" << "matrix_disp_driver" << "mosfets" << "transistors" ; // A name for the example circuit can be generated from the filename (and // will be done so if the filename is not in this list). But the name // generation is not that intelligent (e.g. and.circuit should be called // "AND", not "And" - poor capitalization. And it also allows translation of // names. QStringMap filesToNames; filesToNames["internals.circuit"] = i18n("Internals"); filesToNames["square-wave.circuit"] = i18n("Square Wave"); filesToNames["2-way-switch.circuit"] = i18n("2-Way Switch"); filesToNames["3-way-switch.circuit"] = i18n("3-Way Switch"); filesToNames["capacitor.circuit"] = i18n("Capacitor"); filesToNames["lrc.circuit"] = i18n("LRC"); filesToNames["resistors-parallel.circuit"] = i18n("Resistors in Parallel"); filesToNames["resistors-series.circuit"] = i18n("Resistors in Series"); filesToNames["voltage-divider.circuit"] = i18n("Voltage Divider"); filesToNames["full-wave-rectifier.circuit"] = i18n("Full Wave Rectifier"); filesToNames["half-wave-rectifier.circuit"] = i18n("Half Wave Rectifier"); filesToNames["inverter.circuit"] = i18n("Inverter"); filesToNames["and.circuit"] = i18n("AND"); filesToNames["nand.circuit"] = i18n("NAND"); filesToNames["nor.circuit"] = i18n("NOR"); filesToNames["or.circuit"] = i18n("OR"); filesToNames["decoupler.circuit"] = i18n("Decoupler"); filesToNames["inverting-amplifier.circuit"] = i18n("Inverting Amplifier"); filesToNames["noninverting-amplifier.circuit"] = i18n("Noninverting Amplifier"); filesToNames["instrumentation-amplifier.circuit"] = i18n("Instrumentation Amplifier"); filesToNames["astable-multivibrator.circuit"] = i18n("Astable Multivibrator"); filesToNames["inverter.circuit"] = i18n("Inverter"); filesToNames["scmitt-trigger.circuit"] = i18n("Schmitt Trigger"); filesToNames["switch.circuit"] = i18n("Switch"); filesToNames["matrix_display.circuit"] = i18n("Matrix Display Driver"); int at = 0; QStringList::iterator end = categories.end(); for ( QStringList::iterator it = categories.begin(); it != end; ++it ) { QString category = *it; QDir dir( KStandardDirs::locate( "appdata", "examples/" + category + "/" ) ); //K3PopupMenu * m = static_cast(factory()->container( "examples_" + category, this )); KMenu * m = static_cast(factory()->container( "examples_" + category, this )); if ( !m ) { kWarning() << "failed to cast to popup menu: " << "examples_" + category; continue; } connect( m, SIGNAL(activated( int )), this, SLOT(openExample( int )) ); QStringList files = dir.entryList(); files.remove("."); files.remove(".."); QStringList::iterator filesEnd = files.end(); for ( QStringList::iterator filesIt = files.begin(); filesIt != filesEnd; ++filesIt ) { QString fileName = *filesIt; QString name = filesToNames[ fileName ]; if ( name.isEmpty() ) { name = fileName; name.remove(".circuit"); name.replace("-"," "); name.replace("_"," "); // Capitalize the start of each word bool prevWasSpace = true; for ( unsigned i = 0; i < name.length(); ++i ) { if ( prevWasSpace ) name[i] = name[i].upper(); prevWasSpace = name[i].isSpace(); } } m->insertItem( name, at, at ); m_exampleFiles[ at ] = dir.path() + "/" + fileName; at++; } } } void KTechlab::openExample( int id ) { DocManager::self()->openURL( m_exampleFiles[ id ] ); } void KTechlab::slotViewContainerActivated( QWidget * viewContainer ) { if (!viewContainer) { return; // null viewContainer could be selected, when all documents are closed } m_pFocusedContainer = dynamic_cast(viewContainer); m_pFocusedContainer->setFocus(); } void KTechlab::slotViewContainerDestroyed( QObject * object ) { m_viewContainerList.remove( static_cast(object) ); m_viewContainerList.remove( (ViewContainer*)0 ); slotUpdateTabWidget(); } QAction * KTechlab::actionByName( const QString & name ) const { QAction * action = actionCollection()->action(name); if ( !action ) kError() << k_funcinfo << "No such action: " << name << endl; return action; } void KTechlab::savePropertiesInConfig( KConfig *conf ) { // Dumbass KMainWindow - can't handle my width/height correctly. Whoever thought of the "+1" hack anyway?! //conf->setGroup("UI"); KConfigGroup grUi = conf->group("UI"); grUi.writeEntry( "Width", width() ); grUi.writeEntry( "Height", height() ); //grUi.writeEntry( "WinState", KWin::windowInfo( winId(), NET::WMState ).state() ); grUi.writeEntry( "WinState", (qulonglong) KWindowSystem::windowInfo( winId(), NET::WMState ).state() ); #ifndef NO_GPSIM SymbolViewer::self()->saveProperties( conf ); #endif if ( ProjectManager::self()->currentProject() ) { //conf->setGroup("Project"); KConfigGroup grProject = conf->group("Project"); grProject.writeEntry( "Open", ProjectManager::self()->currentProject()->url().prettyUrl() ); } else { conf->deleteGroup("Project"); } //BEGIN Open Views State // Remvoe old entries describing the save state - we don't want a horrible mish-mash of saved states const QStringList groupList = conf->groupList(); const QStringList::const_iterator groupListEnd = groupList.end(); for ( QStringList::const_iterator it = groupList.begin(); it != groupListEnd; ++it ) { if ( (*it).startsWith("ViewContainer") ) conf->deleteGroup(*it); } uint viewContainerId = 1; const ViewContainerList::iterator vcEnd = m_viewContainerList.end(); for ( ViewContainerList::iterator it = m_viewContainerList.begin(); it != vcEnd; ++it ) { if ( !(*it) || !(*it)->canSaveUsefulStateInfo() ) continue; // To make sure the ViewContainers are restored in the right order, we must create them in alphabetical order, // as KConfig stores them as such... const QString id = QString::number(viewContainerId++).rightJustify( 4, '0' ); //conf->setGroup( "ViewContainer " + id ); KConfigGroup grViewCont = conf->group("ViewContainer " + id); //(*it)->saveState(conf); (*it)->saveState(&grViewCont); } //END Open Views State KConfigGroup grKateMdi = conf->group("KateMDI"); saveSession( &grKateMdi ); // Piss off KMainWindow //conf->setGroup("KateMDI"); int scnum = QApplication::desktop()->screenNumber(parentWidget()); QRect desk = QApplication::desktop()->screenGeometry(scnum); grKateMdi.deleteEntry( QString::fromLatin1("Width %1").arg(desk.width()) ); grKateMdi.deleteEntry( QString::fromLatin1("Height %1").arg(desk.height()) ); conf->sync(); } void KTechlab::readPropertiesInConfig( KConfig *conf ) { startRestore( conf, "KateMDI" ); m_recentFiles->loadEntries(); m_recentProjects->loadEntries(); //BEGIN Restore Open Views if ( KTLConfig::restoreDocumentsOnStartup() ) { // If we have a lot of views open from last time, then opening them will take a long time. // So we want to enter the qt event loop to finish drawing the window et al before adding the views. qApp->processEvents(); const QStringList groupList = conf->groupList(); const QStringList::const_iterator groupListEnd = groupList.end(); for ( QStringList::const_iterator it = groupList.begin(); it != groupListEnd; ++it ) { if ( (*it).startsWith("ViewContainer") ) { ViewContainer *viewContainer = new ViewContainer( *it ); //conf->setGroup(*it); KConfigGroup grIt = conf->group(*it); viewContainer->restoreState( &grIt, *it ); addWindow( viewContainer ); } } } //END Restore Open Views //conf->setGroup("Project"); KConfigGroup grProject = conf->group("Project"); if ( grProject.readEntry("Open") != QString::null ) ProjectManager::self()->slotOpenProject( KUrl( grProject.readEntry("Open") ) ); #ifndef NO_GPSIM SymbolViewer::self()->readProperties( conf ); #endif finishRestore(); // Dumbass KMainWindow - can't handle my width/height correctly. Whoever thought of the "+1" hack anyway?! //conf->setGroup("UI"); KConfigGroup grUi = conf->group("UI"); resize( grUi.readEntry( "Width", 800 ), grUi.readEntry( "Height", 500 ) ); KWindowSystem::setState( winId(), grUi.readEntry( "WinState", (quint32) NET::Max ) ); } void KTechlab::dragEnterEvent(QDragEnterEvent *event) { // accept uri drops only event->accept(K3URLDrag::canDecode(event)); } void KTechlab::dropEvent(QDropEvent *event) { // this is a very simplistic implementation of a drop event. we // will only accept a dropped URL. the Qt dnd code can do *much* // much more, so please read the docs there KUrl::List urls; // see if we can decode a URI.. if not, just ignore it if (K3URLDrag::decode(event, urls) && !urls.isEmpty()) { // okay, we have a URI.. process it const KUrl &url = urls.first(); // load in the file load(url); } } void KTechlab::slotOptionsShowStatusbar() { // this is all very cut and paste code for showing/hiding the // statusbar if (m_statusbarAction->isChecked()) statusBar()->show(); else statusBar()->hide(); } void KTechlab::slotOptionsConfigureKeys() { // KKeyDialog::configureKeys(actionCollection(), "ktechlabui.rc"); KShortcutsDialog::configure( actionCollection(), KShortcutsEditor::LetterShortcutsAllowed, this, true ); } void KTechlab::slotOptionsConfigureToolbars() { KEditToolBar *dlg = new KEditToolBar(guiFactory()); if (dlg->exec()) { createShellGUI( false ); createShellGUI( true ); } delete dlg; } void KTechlab::slotOptionsPreferences() { // An instance of your dialog could be already created and could be cached, // in which case you want to display the cached dialog instead of creating // another one if ( KConfigDialog::showDialog( "settings" ) ) return; // KConfigDialog didn't find an instance of this dialog, so lets create it: SettingsDlg* dialog = new SettingsDlg( this, "settings", KTLConfig::self() ); // User edited the configuration - update your local copies of the // configuration data connect( dialog, SIGNAL(settingsChanged(const QString &)), this, SLOT(slotUpdateConfiguration()) ); dialog->show(); } void KTechlab::slotUpdateConfiguration() { emit configurationChanged(); } void KTechlab::slotChangeStatusbar( const QString & text ) { // Avoid flicker by repeatedly displaying the same message, as QStatusBar does not check for this if ( m_lastStatusBarMessage == text ) return; statusBar()->message(text); m_lastStatusBarMessage = text; } void KTechlab::slotTabContext( QWidget* widget,const QPoint & pos ) { // Shamelessly stolen from KDevelop... K3PopupMenu * tabMenu = new K3PopupMenu; tabMenu->insertTitle( (dynamic_cast(widget))->caption() ); //Find the document on whose tab the user clicked m_pContextMenuContainer = 0l; m_viewContainerList.remove((ViewContainer*)0l); const ViewContainerList::iterator vcEnd = m_viewContainerList.end(); for ( ViewContainerList::iterator it = m_viewContainerList.begin(); it != vcEnd; ++it ) { ViewContainer * viewContainer = *it; if ( viewContainer == widget ) { m_pContextMenuContainer = viewContainer; tabMenu->insertItem( i18n("Close"), 0 ); View *view = (viewContainer->viewCount() == 1) ? viewContainer->activeView() : 0l; if ( view && view->document()->isModified() ) tabMenu->insertItem( i18n("Save"), 1 ); if ( view && !view->document()->url().isEmpty() ) tabMenu->insertItem( i18n("Reload"), 2 ); if ( m_viewContainerList.count() > 1 ) tabMenu->insertItem( i18n("Close All Others"), 4 ); } } connect( tabMenu, SIGNAL( activated(int) ), this, SLOT(slotTabContextActivated(int)) ); tabMenu->exec(pos); delete tabMenu; } void KTechlab::slotTabContextActivated( int id ) { // Shamelessly stolen from KDevelop... if( !m_pContextMenuContainer ) return; View *view = m_pContextMenuContainer->activeView(); if (!view) return; QPointer document = view->document(); switch(id) { case 0: { m_pContextMenuContainer->closeViewContainer(); break; } case 1: document->fileSave(); break; case 2: { KUrl url = document->url(); if ( document->fileClose() ) { delete document; DocManager::self()->openURL(url); } break; } case 4: { const ViewContainerList::iterator vcEnd = m_viewContainerList.end(); for ( ViewContainerList::iterator it = m_viewContainerList.begin(); it != vcEnd; ++it ) { ViewContainer *viewContainer = *it; if ( viewContainer && viewContainer != m_pContextMenuContainer ) { if ( !viewContainer->closeViewContainer() ) return; } } break; } default: break; } } void KTechlab::slotFileNewAssembly() { TextDocument *document = DocManager::self()->createTextDocument(); if (document) document->slotInitLanguage( TextDocument::ct_asm ); } void KTechlab::slotFileNewMicrobe() { TextDocument *document = DocManager::self()->createTextDocument(); if (document) document->slotInitLanguage( TextDocument::ct_microbe ); } void KTechlab::slotFileNewC() { TextDocument *document = DocManager::self()->createTextDocument(); if (document) document->slotInitLanguage( TextDocument::ct_c ); } void KTechlab::slotFileNewCircuit() { DocManager::self()->createCircuitDocument(); } void KTechlab::slotFileNewFlowCode() { slotFileNew(); } void KTechlab::slotFileNewMechanics() { DocManager::self()->createMechanicsDocument(); } void KTechlab::slotFileNew() { NewFileDlg *newFileDlg = new NewFileDlg(this); newFileDlg->exec(); bool addToProject = newFileDlg->addToProject(); bool accepted = newFileDlg->accepted(); int finalType = newFileDlg->fileType(); QString microID = newFileDlg->microID(); int codeType = newFileDlg->codeType(); delete newFileDlg; if (!accepted) return; Document *created = 0l; if ( finalType == Document::dt_circuit ) created = DocManager::self()->createCircuitDocument(); else if ( finalType == Document::dt_flowcode ) { FlowCodeDocument * fcd = DocManager::self()->createFlowCodeDocument(); fcd->setPicType(microID); created = fcd; } else if ( finalType == Document::dt_mechanics ) created = DocManager::self()->createMechanicsDocument(); else { // Presumably a text document TextDocument * textDocument = DocManager::self()->createTextDocument(); if (textDocument) textDocument->slotInitLanguage( (TextDocument::CodeType)codeType ); created = textDocument; } if ( created && addToProject ) created->setAddToProjectOnSave(true); } void KTechlab::slotFileOpen() { // this slot is called whenever the File->Open menu is selected, // the Open shortcut is pressed (usually CTRL+O) or the Open toolbar // button is clicked // standard filedialog KUrl::List urls = getFileURLs(); const KUrl::List::iterator end = urls.end(); for ( KUrl::List::iterator it = urls.begin(); it != end; ++ it) load(*it); } void KTechlab::addRecentFile( const KUrl &url ) { m_recentFiles->addURL( url ); emit recentFileAdded(url); } KUrl::List KTechlab::getFileURLs( bool allowMultiple ) { QString filter; filter = QString("*|%1\n" "*.asm *.src *.inc|%2 (*.asm, *.src, *.inc)\n" "*.hex|%3 (*.hex)\n" "*.circuit|%4 (*.circuit)\n" "*.flowcode|FlowCode (*.flowcode)\n" "*.basic *.microbe|Microbe (*.microbe, *.basic)" /*"*.mechanics|Mechanics (*.mechanics)\n"*/) .arg(i18n("All Files")) .arg(i18n("Assembly Code")) .arg(i18n("Intel Hex")) .arg(i18n("Circuit")); if ( allowMultiple ) return KFileDialog::getOpenUrls( KUrl(), filter, 0l, i18n("Open Location") ); else return KFileDialog::getOpenUrl( KUrl(), filter, 0l, i18n("Open Location") ); } void KTechlab::slotDocModifiedChanged() { //BEGIN Set tab icons KIconLoader *loader = KIconLoader::global(); const ViewContainerList::iterator vcEnd = m_viewContainerList.end(); for ( ViewContainerList::iterator it = m_viewContainerList.begin(); it != vcEnd; ++it ) { ViewContainer * vc = *it; if ( !vc || !vc->activeView() || !vc->activeView()->document() ) continue; QPixmap iconPixmap; if ( vc->activeView()->document()->isModified() ) { iconPixmap = loader->loadIcon( "filesave", KIconLoader::Small ); } else { switch ( vc->activeView()->document()->type() ) { case Document::dt_circuit: iconPixmap = loader->loadIcon( "ktechlab_circuit", KIconLoader::Small ); break; case Document::dt_flowcode: iconPixmap = loader->loadIcon( "ktechlab_flowcode", KIconLoader::Small ); break; case Document::dt_mechanics: iconPixmap = loader->loadIcon( "ktechlab_mechanics", KIconLoader::Small ); break; case Document::dt_text: iconPixmap = loader->loadIcon( "text-x-generic", KIconLoader::Small ); break; case Document::dt_pinMapEditor: break; case Document::dt_none: iconPixmap = loader->loadIcon( "application-x-zerosize", KIconLoader::Small ); break; } } tabWidget()->setTabIconSet( vc, iconPixmap ); } //END Set tab icons } void KTechlab::requestUpdateCaptions() { m_pUpdateCaptionsTimer->start( 0, true ); } void KTechlab::slotUpdateCaptions() { //BEGIN Set KTechlab caption Document *document = DocManager::self()->getFocusedDocument(); QString newCaption; if ( document ) { KUrl url = document->url(); if ( url.isEmpty() ) newCaption = document->caption(); else { if ( url.isLocalFile() && url.ref().isNull() && url.query().isNull() ) newCaption = url.path(); else newCaption = url.prettyUrl(); } } else newCaption = ""; if (newCaption != caption().remove(" - KTechlab")) setCaption(newCaption); //END Set KTechlab caption //BEGIN Set tab captions emit needUpdateCaptions(); if ( document && document->activeView() && document->activeView()->viewContainer() ) { document->activeView()->viewContainer()->updateCaption(); } //END Set tab captions } void KTechlab::slotDocUndoRedoChanged() { Document *document = DocManager::self()->getFocusedDocument(); if (!document) return; action("edit_undo")->setEnabled( document->isUndoAvailable() ); action("edit_redo")->setEnabled( document->isRedoAvailable() ); } void KTechlab::slotFileSave() { Document *document = DocManager::self()->getFocusedDocument(); if (document) document->fileSave(); } void KTechlab::slotFileSaveAs() { Document *document = DocManager::self()->getFocusedDocument(); if (document) document->fileSaveAs(); } void KTechlab::slotFilePrint() { Document *document = DocManager::self()->getFocusedDocument(); if (document) document->print(); } bool KTechlab::queryClose() { KConfig *cfgPtr = KGlobal::config().data(); //saveProperties( KGlobal::config() ); savePropertiesInConfig( cfgPtr ); if ( DocManager::self()->closeAll() && ProjectManager::self()->slotCloseProject() ) { // Make ourself "deleted" m_pSelf = 0l; return true; } return false; } void KTechlab::slotFileQuit() { // close the first window, the list makes the next one the first again. // This ensures that queryClose() is called on each window to ask for closing //KMainWindow* w; if(!memberList().isEmpty()) { QList mainWindowList = memberList(); //for( w=memberList->first(); w!=0; w=memberList->next() ) for(QList::iterator itWnd = mainWindowList.begin(); itWnd != mainWindowList.end(); ++itWnd) { // only close the window if the closeEvent is accepted. If the user presses Cancel on the saveModified() dialog, // the window and the application stay open. //if( !w->close() ) break; if( !(*itWnd)->close() ) break; } } slotChangeStatusbar( i18n("Exiting...") ); } void KTechlab::slotEditUndo() { Document *document = DocManager::self()->getFocusedDocument(); if (document) document->undo(); } void KTechlab::slotEditRedo() { Document *document = DocManager::self()->getFocusedDocument(); if (document) document->redo(); } void KTechlab::slotEditCut() { Document *document = DocManager::self()->getFocusedDocument(); if (document) document->cut(); } void KTechlab::slotEditCopy() { Document *document = DocManager::self()->getFocusedDocument(); if (document) document->copy(); } void KTechlab::slotEditPaste() { Document *document = DocManager::self()->getFocusedDocument(); if (document) document->paste(); } void KTechlab::slotViewContainerClose() { if (m_pFocusedContainer) m_pFocusedContainer->closeViewContainer(); } void KTechlab::slotViewClose() { View *view = DocManager::self()->getFocusedView(); if (view) view->closeView(); } void KTechlab::slotViewSplitLeftRight() { View *view = DocManager::self()->getFocusedView(); if (!view) return; ViewContainer *vc = view->viewContainer(); uint vaId = vc->createViewArea( view->viewAreaId(), ViewArea::Right, true ); // view->document()->createView( vc, vaId ); (void)vaId; } void KTechlab::slotViewSplitTopBottom() { View *view = DocManager::self()->getFocusedView(); if (!view) return; ViewContainer *vc = view->viewContainer(); uint vaId = vc->createViewArea( view->viewAreaId(), ViewArea::Bottom, true ); // view->document()->createView( vc, vaId ); (void)vaId; } #include "ktechlab.moc" diff --git a/src/languages/languagemanager.cpp b/src/languages/languagemanager.cpp index e4d4d3fe..33408146 100644 --- a/src/languages/languagemanager.cpp +++ b/src/languages/languagemanager.cpp @@ -1,106 +1,105 @@ /*************************************************************************** * Copyright (C) 2005 by David Saxton * * david@bluehaze.org * * * * 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 "docmanager.h" #include "languagemanager.h" #include "logview.h" #include "ktechlab.h" #include "k3tempfile.h" #include "src/core/ktlconfig.h" #include "outputmethoddlg.h" #include "processchain.h" #include "projectmanager.h" #include "microbe.h" #include "gpasm.h" #include "gpdasm.h" #include #include #include -#include #include LanguageManager * LanguageManager::m_pSelf = 0l; LanguageManager * LanguageManager::self( KateMDI::ToolView * parent ) { if (!m_pSelf) { assert(parent); m_pSelf = new LanguageManager( parent ); } return m_pSelf; } LanguageManager::LanguageManager( KateMDI::ToolView * parent ) : QObject( KTechlab::self() ) { m_logView = new LogView( parent, "LanguageManager LogView"); - QWhatsThis::add( m_logView, i18n("These messages show the output of language-related functionality such as compiling and assembling.

For error messages, clicking on the line will automatically open up the file at the position of the error.") ); + m_logView->setWhatsThis( i18n("These messages show the output of language-related functionality such as compiling and assembling.

For error messages, clicking on the line will automatically open up the file at the position of the error.") ); connect( m_logView, SIGNAL(paraClicked(const QString&, MessageInfo )), this, SLOT(slotParaClicked(const QString&, MessageInfo )) ); reset(); } LanguageManager::~LanguageManager() { } void LanguageManager::reset() { m_logView->clear(); } ProcessChain * LanguageManager::compile( ProcessOptions options ) { if ( KTLConfig::raiseMessagesLog() ) KTechlab::self()->showToolView( KTechlab::self()->toolView( toolViewIdentifier() ) ); return new ProcessChain( options ); } ProcessListChain * LanguageManager::compile( ProcessOptionsList pol ) { if ( KTLConfig::raiseMessagesLog() ) KTechlab::self()->showToolView( KTechlab::self()->toolView( toolViewIdentifier() ) ); return new ProcessListChain( pol ); } void LanguageManager::slotError( const QString &error, MessageInfo messageInfo ) { m_logView->addOutput( error, LogView::ot_error, messageInfo ); } void LanguageManager::slotWarning( const QString &error, MessageInfo messageInfo ) { m_logView->addOutput( error, LogView::ot_warning, messageInfo ); } void LanguageManager::slotMessage( const QString &error, MessageInfo messageInfo ) { m_logView->addOutput( error, LogView::ot_message, messageInfo ); } void LanguageManager::slotParaClicked( const QString& message, MessageInfo messageInfo ) { Q_UNUSED(message); DocManager::self()->gotoTextLine( messageInfo.fileURL(), messageInfo.fileLine() ); } #include "languagemanager.moc" diff --git a/src/projectmanager.cpp b/src/projectmanager.cpp index 13bcf92e..98303467 100644 --- a/src/projectmanager.cpp +++ b/src/projectmanager.cpp @@ -1,1266 +1,1265 @@ /*************************************************************************** * Copyright (C) 2003-2005 by David Saxton * * david@bluehaze.org * * * * 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 "core/ktlconfig.h" #include "docmanager.h" #include "document.h" #include "language.h" #include "languagemanager.h" #include "ktechlab.h" #include "microselectwidget.h" #include "programmerdlg.h" #include "projectdlgs.h" #include "projectmanager.h" #include "recentfilesaction.h" #include #include #include #include #include #include #include #include #include #include #include -#include #include //BEGIN class LinkerOptions LinkerOptions::LinkerOptions() { m_hexFormat = HexFormat::inhx32; m_bOutputMapFile = false; } QDomElement LinkerOptions::toDomElement( QDomDocument & doc, const KUrl & baseURL ) const { QDomElement node = doc.createElement("linker"); node.setAttribute( "hex-format", hexFormatToString(hexFormat()) ); node.setAttribute( "output-map-file", outputMapFile() ); node.setAttribute( "library-dir", libraryDir() ); node.setAttribute( "linker-script", linkerScript() ); node.setAttribute( "other", linkerOther() ); QStringList::const_iterator end = m_linkedInternal.end(); for ( QStringList::const_iterator it = m_linkedInternal.begin(); it != end; ++it ) { QDomElement child = doc.createElement("linked-internal"); node.appendChild(child); child.setAttribute( "url", KUrl::relativeUrl( baseURL, *it ) ); } end = m_linkedExternal.end(); for ( QStringList::const_iterator it = m_linkedExternal.begin(); it != end; ++it ) { QDomElement child = doc.createElement("linked-external"); node.appendChild(child); child.setAttribute( "url", *it ); } return node; } void LinkerOptions::domElementToLinkerOptions( const QDomElement & element, const KUrl & baseURL ) { setHexFormat( stringToHexFormat( element.attribute( "hex-format", QString::null ) ) ); setOutputMapFile( element.attribute( "output-map-file", "0" ).toInt() ); setLibraryDir( element.attribute( "library-dir", QString::null ) ); setLinkerScript( element.attribute( "linker-script", QString::null ) ); setLinkerOther( element.attribute( "other", QString::null ) ); m_linkedInternal.clear(); m_linkedExternal.clear(); QDomNode node = element.firstChild(); while ( !node.isNull() ) { QDomElement childElement = node.toElement(); if ( !childElement.isNull() ) { const QString tagName = childElement.tagName(); if ( tagName == "linked-internal" ) m_linkedInternal << KUrl( baseURL, childElement.attribute( "url", QString::null ) ).url(); else if ( tagName == "linked-external" ) m_linkedExternal << childElement.attribute( "url", QString::null ); else kError() << k_funcinfo << "Unrecognised element tag name: "<deleteLater(); m_children.clear(); delete m_pILVItem; } void ProjectItem::setILVItem( ILVItem * ilvItem ) { m_pILVItem = ilvItem; ilvItem->setOpen(true); ilvItem->setText( 0, name() ); ilvItem->setProjectItem(this); updateILVItemPixmap(); } void ProjectItem::updateILVItemPixmap() { if ( !m_pILVItem ) return; switch ( type() ) { case ProjectType: { // ?! - We shouldn't have an ilvitem for this. break; } case ProgramType: { QPixmap pm; pm.load( KStandardDirs:: locate( "appdata", "icons/project_program.png" ) ); m_pILVItem->setPixmap( 0, pm ); break; } case LibraryType: { QPixmap pm; pm.load( KStandardDirs:: locate( "appdata", "icons/project_library.png" ) ); m_pILVItem->setPixmap( 0, pm ); break; } case FileType: { KMimeType::Ptr m = KMimeType::findByPath( url().path() ); //m_pILVItem->setPixmap( 0, m->pixmap( KIconLoader::Small ) ); m_pILVItem->setPixmap( 0, KIconLoader::global()->loadMimeTypeIcon( m->iconName(), KIconLoader::Small ) ); break; } } } void ProjectItem::addChild( ProjectItem * child ) { if ( !child || m_children.contains(child) ) return; m_children << child; child->setILVItem( m_pILVItem ? new ILVItem( m_pILVItem, child->name() ) : new ILVItem( m_pProjectManager, name() ) ); updateControlChildMicroIDs(); } void ProjectItem::updateControlChildMicroIDs() { bool control = false; switch ( type() ) { case ProjectItem::ProjectType: case ProjectItem::LibraryType: case ProjectItem::ProgramType: control = !microID().isEmpty(); break; case ProjectItem::FileType: control = true; break; } m_children.remove( (ProjectItem*)0l ); ProjectItemList::iterator end = m_children.end(); for ( ProjectItemList::iterator it = m_children.begin(); it != end; ++it ) (*it)->setUseParentMicroID( control ); } void ProjectItem::setName( const QString & name ) { m_name = name; if (m_pILVItem) m_pILVItem->setText( 0, name ); } void ProjectItem::setURL( const KUrl & url ) { m_url = url; if ( m_name.isEmpty() ) setName( url.fileName() ); if ( type() != FileType ) { // The output url *is* our url setOutputURL(url); } else if ( outputURL().isEmpty() ) { // Try and guess what the output url should be... QString newExtension; switch ( outputType() ) { case ProgramOutput: newExtension = ".hex"; break; case ObjectOutput: newExtension = ".o"; break; case LibraryOutput: newExtension = ".o"; break; case UnknownOutput: break; } if ( !newExtension.isEmpty() ) { const QString fileName = url.url(); QString extension = fileName.right( fileName.length() - fileName.findRev('.') ); setOutputURL( QString(fileName).replace( extension, newExtension ) ); } } updateILVItemPixmap(); } QString ProjectItem::microID() const { if ( !m_bUseParentMicroID ) return m_microID; return m_pParent ? m_pParent->microID() : QString::null; } void ProjectItem::setMicroID( const QString & id ) { ProcessingOptions::setMicroID(id); updateControlChildMicroIDs(); } ProjectItem::OutputType ProjectItem::outputType() const { if ( !m_pParent ) return UnknownOutput; switch ( m_pParent->type() ) { case ProjectItem::ProjectType: { // We're a top level build target, so look at our own type switch ( type() ) { case ProjectItem::ProjectType: kWarning() << k_funcinfo << "Parent item and this item are both project items" << endl; return UnknownOutput; case ProjectItem::FileType: case ProjectItem::ProgramType: return ProgramOutput; case ProjectItem::LibraryType: return LibraryOutput; } return UnknownOutput; } case ProjectItem::FileType: { kWarning() << k_funcinfo << "Don't know how to handle parent item being a file" << endl; return UnknownOutput; } case ProjectItem::ProgramType: case ProjectItem::LibraryType: return ObjectOutput; } return UnknownOutput; } bool ProjectItem::build( ProcessOptionsList * pol ) { if ( !pol ) return false; // Check to see that we aren't already in the ProcessOptionstList; ProcessOptionsList::iterator polEnd = pol->end(); for ( ProcessOptionsList::iterator it = pol->begin(); it != polEnd; ++it ) { if ( (*it).targetFile() == outputURL().path() ) return true; } ProjectInfo * projectInfo = ProjectManager::self()->currentProject(); assert(projectInfo); if ( outputURL().isEmpty() ) { KMessageBox::sorry( 0l, i18n("Do not know how to build \"%1\" (output URL is empty).", name()) ); return false; } // Build all internal libraries that we depend on QStringList::iterator send = m_linkedInternal.end(); for ( QStringList::iterator it = m_linkedInternal.begin(); it != send; ++it ) { ProjectItem * lib = projectInfo->findItem( projectInfo->directory() + *it ); if ( !lib ) { KMessageBox::sorry( 0l, i18n("Do not know how to build \"%1\" (library does not exist in project).", *it) ); return false; } if ( !lib->build(pol) ) return false; } // Build all children m_children.remove( (ProjectItem*)0l ); ProjectItemList::iterator cend = m_children.end(); for ( ProjectItemList::iterator it = m_children.begin(); it != cend; ++it ) { if ( ! (*it)->build(pol) ) return false; } // Now build ourself ProcessOptions po; po.b_addToProject = false; po.setTargetFile( outputURL().path() ); po.m_picID = microID(); ProcessOptions::ProcessPath::MediaType typeTo = ProcessOptions::ProcessPath::Unknown; switch ( outputType() ) { case UnknownOutput: KMessageBox::sorry( 0l, i18n("Do not know how to build \"%1\" (unknown output type).", name()) ); return false; case ProgramOutput: typeTo = ProcessOptions::ProcessPath::Program; break; case ObjectOutput: typeTo = ProcessOptions::ProcessPath::Object; break; case LibraryOutput: typeTo = ProcessOptions::ProcessPath::Library; break; } switch ( type() ) { case ProjectType: // Nothing to do return true; case FileType: po.setInputFiles( QStringList( url().path() ) ); po.setProcessPath( ProcessOptions::ProcessPath::path( ProcessOptions::guessMediaType( url().url() ), typeTo ) ); break; case ProgramType: case LibraryType: // Build up a list of input urls QStringList inputFiles; // Link child objects m_children.remove( (ProjectItem*)0l ); ProjectItemList::iterator cend = m_children.end(); for ( ProjectItemList::iterator it = m_children.begin(); it != cend; ++it ) inputFiles << (*it)->outputURL().path(); po.setInputFiles(inputFiles); po.setProcessPath( ProcessOptions::ProcessPath::path( ProcessOptions::ProcessPath::Object, typeTo ) ); break; } po.m_hexFormat = hexFormatToString( hexFormat() ); po.m_bOutputMapFile = outputMapFile(); po.m_libraryDir = libraryDir(); po.m_linkerScript = linkerScript(); po.m_linkOther = linkerOther(); // Link against libraries QStringList::iterator lend = m_linkedInternal.end(); for ( QStringList::iterator it = m_linkedInternal.begin(); it != lend; ++it ) po.m_linkLibraries += projectInfo->directory() + *it; lend = m_linkedExternal.end(); for ( QStringList::iterator it = m_linkedExternal.begin(); it != lend; ++it ) po.m_linkLibraries += *it; // Save our working file (if open) and append to the build list Document * currentDoc = DocManager::self()->findDocument( url() ); if (currentDoc) currentDoc->fileSave(); pol->append(po); return true; } void ProjectItem::upload( ProcessOptionsList * pol ) { build( pol ); ProgrammerDlg * dlg = new ProgrammerDlg( microID(), (QWidget*)KTechlab::self(), "Programmer Dlg" ); dlg->exec(); if ( !dlg->isAccepted() ) { dlg->deleteLater(); return; } ProcessOptions po; dlg->initOptions( & po ); po.b_addToProject = false; po.setInputFiles( QStringList( outputURL().path() ) ); po.setProcessPath( ProcessOptions::ProcessPath::Program_PIC ); pol->append( po ); dlg->deleteLater(); } QDomElement ProjectItem::toDomElement( QDomDocument & doc, const KUrl & baseURL ) const { QDomElement node = doc.createElement("item"); node.setAttribute( "type", typeToString() ); node.setAttribute( "name", m_name ); node.setAttribute( "url", KUrl::relativeUrl( baseURL, m_url.url() ) ); node.appendChild( LinkerOptions::toDomElement( doc, baseURL ) ); node.appendChild( ProcessingOptions::toDomElement( doc, baseURL ) ); ProjectItemList::const_iterator end = m_children.end(); for ( ProjectItemList::const_iterator it = m_children.begin(); it != end; ++it ) { if (*it) node.appendChild( (*it)->toDomElement( doc, baseURL ) ); } return node; } KUrl::List ProjectItem::childOutputURLs( unsigned types, unsigned outputTypes ) const { KUrl::List urls; ProjectItemList::const_iterator end = m_children.end(); for ( ProjectItemList::const_iterator it = m_children.begin(); it != end; ++it ) { if (!*it) continue; if ( ((*it)->type() & types) && ((*it)->outputType() & outputTypes) ) urls += (*it)->outputURL().prettyUrl(); urls += (*it)->childOutputURLs(types); } return urls; } ProjectItem * ProjectItem::findItem( const KUrl & url ) { if ( this->url() == url ) return this; ProjectItemList::const_iterator end = m_children.end(); for ( ProjectItemList::const_iterator it = m_children.begin(); it != end; ++it ) { if (!*it) continue; ProjectItem * found = (*it)->findItem(url); if (found) return found; } return 0l; } bool ProjectItem::closeOpenFiles() { Document * doc = DocManager::self()->findDocument(m_url); if ( doc && !doc->fileClose() ) return false; m_children.remove( (ProjectItem*)0l ); ProjectItemList::iterator end = m_children.end(); for ( ProjectItemList::iterator it = m_children.begin(); it != end; ++it ) { if ( !(*it)->closeOpenFiles() ) return false; } return true; } void ProjectItem::addFiles() { KUrl::List urls = KTechlab::self()->getFileURLs(); const KUrl::List::iterator end = urls.end(); for ( KUrl::List::iterator it = urls.begin(); it != end; ++ it) addFile(*it); } void ProjectItem::addCurrentFile() { Document *document = DocManager::self()->getFocusedDocument(); if (!document) return; // If the file isn't saved yet, we must do that // before it is added to the project. if( document->url().isEmpty() ) { document->fileSaveAs(); // If the user pressed cancel then just give up, // otherwise the file can now be added. } if( !document->url().isEmpty() ) addFile( document->url() ); } void ProjectItem::addFile( const KUrl & url ) { if ( url.isEmpty() ) return; m_children.remove( (ProjectItem*)0l ); ProjectItemList::iterator end = m_children.end(); for ( ProjectItemList::iterator it = m_children.begin(); it != end; ++it ) { if ( (*it)->type() == FileType && (*it)->url() == url ) return; } ProjectItem * item = new ProjectItem( this, FileType, m_pProjectManager ); item->setURL(url); addChild(item); } QString ProjectItem::typeToString() const { switch (m_type) { case ProjectType: return "Project"; case FileType: return "File"; case ProgramType: return "Program"; case LibraryType: return "Library"; } return QString::null; } ProjectItem::Type ProjectItem::stringToType( const QString & type ) { if ( type == "Project" ) return ProjectType; if ( type == "File" ) return FileType; if ( type == "Program" ) return ProgramType; if ( type == "Library" ) return LibraryType; return FileType; } void ProjectItem::domElementToItem( const QDomElement & element, const KUrl & baseURL ) { Type type = stringToType( element.attribute( "type", QString::null ) ); QString name = element.attribute( "name", QString::null ); KUrl url( baseURL, element.attribute( "url", QString::null ) ); ProjectItem * createdItem = new ProjectItem( this, type, m_pProjectManager ); createdItem->setName( name ); createdItem->setURL( url ); addChild( createdItem ); QDomNode node = element.firstChild(); while ( !node.isNull() ) { QDomElement childElement = node.toElement(); if ( !childElement.isNull() ) { const QString tagName = childElement.tagName(); if ( tagName == "linker" ) createdItem->domElementToLinkerOptions( childElement, baseURL ); else if ( tagName == "processing" ) createdItem->domElementToProcessingOptions( childElement, baseURL ); else if ( tagName == "item" ) createdItem->domElementToItem( childElement, baseURL ); else kError() << k_funcinfo << "Unrecognised element tag name: "<toDomElement( doc, m_url ) ); QTextStream stream(&file); stream << doc.toString(); file.close(); { QAction *recentfilesaction = KTechlab::self()->actionByName("project_open_recent"); if (recentfilesaction) { (static_cast(recentfilesaction))->addURL(m_url); } else { qWarning() << "there is no project_open_recent action in KTechLab!"; } } return true; } bool ProjectInfo::saveAndClose() { if (!save()) return false; if (!closeOpenFiles()) return false; return true; } //END class ProjectInfo //BEGIN class ProjectManager ProjectManager * ProjectManager::m_pSelf = 0l; ProjectManager * ProjectManager::self( KateMDI::ToolView * parent ) { if ( !m_pSelf ) { assert(parent); m_pSelf = new ProjectManager( parent ); } return m_pSelf; } ProjectManager::ProjectManager( KateMDI::ToolView * parent ) : ItemSelector( parent, "Project Manager" ), m_pCurrentProject(0l) { - QWhatsThis::add( this, i18n("Displays the list of files in the project.\nTo open or close a project, use the \"Project\" menu. Right click on a file to remove it from the project") ); + setWhatsThis( i18n("Displays the list of files in the project.\nTo open or close a project, use the \"Project\" menu. Right click on a file to remove it from the project") ); setListCaption( i18n("File") ); setCaption( i18n("Project Manager") ); connect( this, SIGNAL(clicked(Q3ListViewItem*)), this, SLOT(slotItemClicked(Q3ListViewItem*)) ); } ProjectManager::~ProjectManager() { } void ProjectManager::slotNewProject() { if ( !slotCloseProject() ) return; NewProjectDlg *newProjectDlg = new NewProjectDlg(this); newProjectDlg->exec(); if ( newProjectDlg->accepted() ) { m_pCurrentProject = new ProjectInfo( this ); m_pCurrentProject->setName( newProjectDlg->projectName() ); m_pCurrentProject->setURL( newProjectDlg->location() + m_pCurrentProject->name().lower() + ".ktechlab" ); QDir dir; if ( !dir.mkdir( m_pCurrentProject->directory() ) ) kDebug() << "Error in creating directory " << m_pCurrentProject->directory() << endl; m_pCurrentProject->save(); updateActions(); emit projectCreated(); } delete newProjectDlg; } void ProjectManager::slotProjectOptions() { } void ProjectManager::slotOpenProject() { QString filter; filter = QString("*.ktechlab|%1 (*.ktechlab)\n*|%2").arg( i18n("KTechlab Project") ).arg( i18n("All Files") ); KUrl url = KFileDialog::getOpenUrl( KUrl(), filter, this, i18n("Open Location")); if ( url.isEmpty() ) return; slotOpenProject(url); } void ProjectManager::slotOpenProject( const KUrl & url ) { if ( m_pCurrentProject && m_pCurrentProject->url() == url ) return; if ( !slotCloseProject() ) return; m_pCurrentProject = new ProjectInfo( this ); if ( !m_pCurrentProject->open(url) ) { m_pCurrentProject->deleteLater(); m_pCurrentProject = 0l; return; } { RecentFilesAction * rfa = static_cast(KTechlab::self()->actionByName("project_open_recent")); if (rfa) { rfa->addURL( m_pCurrentProject->url() ); } else { qWarning() << "there is no project_open_recent action in application"; } } if ( KTLConfig::raiseItemSelectors() ) KTechlab::self()->showToolView( KTechlab::self()->toolView( toolViewIdentifier() ) ); updateActions(); emit projectOpened(); } bool ProjectManager::slotCloseProject() { if ( !m_pCurrentProject ) return true; if ( !m_pCurrentProject->saveAndClose() ) return false; m_pCurrentProject->deleteLater(); m_pCurrentProject = 0l; updateActions(); emit projectClosed(); return true; } void ProjectManager::slotCreateSubproject() { if ( !currentProject() ) return; CreateSubprojectDlg * dlg = new CreateSubprojectDlg(this); dlg->exec(); if ( dlg->accepted() ) { ProjectItem::Type type = ProjectItem::ProgramType; switch ( dlg->type() ) { case CreateSubprojectDlg::ProgramType: type = ProjectItem::ProgramType; break; case CreateSubprojectDlg::LibraryType: type = ProjectItem::LibraryType; break; } ProjectItem * subproject = new ProjectItem( currentProject(), type, this ); subproject->setURL( dlg->targetFile() ); currentProject()->addChild(subproject); currentProject()->save(); emit subprojectCreated(); } delete dlg; } void ProjectManager::updateActions() { bool projectIsOpen = m_pCurrentProject; KTechlab::self()->actionByName("project_create_subproject")->setEnabled( projectIsOpen ); KTechlab::self()->actionByName("project_export_makefile")->setEnabled( projectIsOpen ); KTechlab::self()->actionByName("subproject_add_existing_file")->setEnabled( projectIsOpen ); KTechlab::self()->actionByName("subproject_add_current_file")->setEnabled( projectIsOpen ); // KTechlab::self()->actionByName("project_options")->setEnabled( projectIsOpen ); KTechlab::self()->actionByName("project_close")->setEnabled( projectIsOpen ); KTechlab::self()->actionByName("project_add_existing_file")->setEnabled( projectIsOpen ); KTechlab::self()->actionByName("project_add_current_file")->setEnabled( projectIsOpen ); } void ProjectManager::slotAddFile() { if ( !currentProject() ) return; currentProject()->addFiles(); emit filesAdded(); } void ProjectManager::slotAddCurrentFile() { if ( !currentProject() ) return; currentProject()->addCurrentFile(); emit filesAdded(); } void ProjectManager::slotSubprojectAddExistingFile() { ILVItem * currentItem = dynamic_cast(selectedItem()); if ( !currentItem || !currentItem->projectItem() ) return; currentItem->projectItem()->addFiles(); emit filesAdded(); } void ProjectManager::slotSubprojectAddCurrentFile() { ILVItem * currentItem = dynamic_cast(selectedItem()); if ( !currentItem || !currentItem->projectItem() ) return; currentItem->projectItem()->addCurrentFile(); emit filesAdded(); } void ProjectManager::slotItemBuild() { ILVItem * currentItem = dynamic_cast(selectedItem()); if ( !currentItem || !currentItem->projectItem() ) return; ProcessOptionsList pol; currentItem->projectItem()->build(&pol); LanguageManager::self()->compile(pol); } void ProjectManager::slotItemUpload() { ILVItem * currentItem = dynamic_cast(selectedItem()); if ( !currentItem || !currentItem->projectItem() ) return; ProcessOptionsList pol; currentItem->projectItem()->upload(&pol); LanguageManager::self()->compile(pol); } void ProjectManager::slotRemoveSelected() { ILVItem *currentItem = dynamic_cast(selectedItem()); if ( !currentItem ) return; int choice = KMessageBox::questionYesNo( this, i18n("Do you really want to remove \"%1\"?", currentItem->text(0) ), i18n("Remove Project File?"), KGuiItem(i18n("Remove")), KGuiItem(i18n("Cancel")) ); if ( choice == KMessageBox::No ) return; currentItem->projectItem()->deleteLater(); emit filesRemoved(); } void ProjectManager::slotExportToMakefile() { } void ProjectManager::slotSubprojectLinkerOptions() { ILVItem * currentItem = dynamic_cast(selectedItem()); if ( !currentItem || !currentItem->projectItem() ) return; LinkerOptionsDlg * dlg = new LinkerOptionsDlg( currentItem->projectItem(), this ); dlg->exec(); currentProject()->save(); // The dialog sets the options for us if it was accepted, so we don't need to do anything delete dlg; } void ProjectManager::slotItemProcessingOptions() { ILVItem * currentItem = dynamic_cast(selectedItem()); if ( !currentItem || !currentItem->projectItem() ) return; ProcessingOptionsDlg * dlg = new ProcessingOptionsDlg( currentItem->projectItem(), this ); dlg->exec(); currentProject()->save(); // The dialog sets the options for us if it was accepted, so we don't need to do anything delete dlg; } void ProjectManager::slotItemClicked( Q3ListViewItem * item ) { ILVItem * ilvItem = dynamic_cast(item); if ( !ilvItem ) return; ProjectItem * projectItem = ilvItem->projectItem(); if ( !projectItem || projectItem->type() != ProjectItem::FileType ) return; DocManager::self()->openURL( projectItem->url() ); } void ProjectManager::slotContextMenuRequested( Q3ListViewItem* item, const QPoint& pos, int col /*col*/ ) { QString popupName; ILVItem * ilvItem = dynamic_cast(item); QAction * linkerOptionsAct = KTechlab::self()->actionByName("project_item_linker_options"); linkerOptionsAct->setEnabled(false); if ( !m_pCurrentProject ) popupName = "project_none_popup"; else if ( !ilvItem ) popupName = "project_blank_popup"; else { ProcessOptions::ProcessPath::MediaType mediaType = ProcessOptions::guessMediaType( ilvItem->projectItem()->url().url() ); switch ( ilvItem->projectItem()->type() ) { case ProjectItem::FileType: if ( mediaType == ProcessOptions::ProcessPath::Unknown ) popupName = "project_file_other_popup"; else popupName = "project_file_popup"; break; case ProjectItem::ProgramType: popupName = "project_program_popup"; break; case ProjectItem::LibraryType: popupName = "project_library_popup"; break; case ProjectItem::ProjectType: return; } switch ( ilvItem->projectItem()->outputType() ) { case ProjectItem::ProgramOutput: linkerOptionsAct->setEnabled(true); break; case ProjectItem::ObjectOutput: case ProjectItem::LibraryOutput: case ProjectItem::UnknownOutput: linkerOptionsAct->setEnabled(false); break; } // Only have linking options for SDCC files linkerOptionsAct->setEnabled( mediaType == ProcessOptions::ProcessPath::C ); } bool haveFocusedDocument = DocManager::self()->getFocusedDocument(); KTechlab::self()->actionByName("subproject_add_current_file")->setEnabled( haveFocusedDocument ); KTechlab::self()->actionByName("project_add_current_file")->setEnabled( haveFocusedDocument ); Q3PopupMenu *pop = static_cast(KTechlab::self()->factory()->container( popupName, KTechlab::self() )); if (pop) pop->popup(pos); } //END class ProjectManager #include "projectmanager.moc"