00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "circuitdocument.h"
00012 #include "config.h"
00013 #include "contexthelp.h"
00014 #include "docmanager.h"
00015 #include "filemetainfo.h"
00016 #include "flowcodedocument.h"
00017 #include "itemeditor.h"
00018 #include "itemgroup.h"
00019 #include "iteminterface.h"
00020 #include "itemlibrary.h"
00021 #include "ktechlab.h"
00022 #include "core/ktlconfig.h"
00023 #include "languagemanager.h"
00024 #include "mechanicsdocument.h"
00025 #include "microlibrary.h"
00026 #include "newfiledlg.h"
00027 #include "oscilloscope.h"
00028 #include "projectmanager.h"
00029 #include "recentfilesaction.h"
00030 #include "settingsdlg.h"
00031 #include "subcircuits.h"
00032 #include "symbolviewer.h"
00033 #include "textdocument.h"
00034 #include "textview.h"
00035 #include "viewcontainer.h"
00036
00037 #include <qdockarea.h>
00038 #include <qtimer.h>
00039 #include <qtoolbutton.h>
00040 #include <qwhatsthis.h>
00041
00042 #include <kaccel.h>
00043 #include <kapplication.h>
00044 #include <kdebug.h>
00045 #include <kedittoolbar.h>
00046 #include <kfiledialog.h>
00047 #include <kiconloader.h>
00048 #include <kio/netaccess.h>
00049 #include <kkeydialog.h>
00050 #include <klocale.h>
00051 #include <kmessagebox.h>
00052 #include <kpopupmenu.h>
00053 #include <kstandarddirs.h>
00054 #include <ktabwidget.h>
00055 #include <kurldrag.h>
00056 #include <kwin.h>
00057
00058 KTechlab::KTechlab()
00059 : KateMDI::MainWindow( 0, "KTechlab" )
00060 {
00061 QTime ct;
00062 ct.start();
00063
00064 m_bIsShown = false;
00065 m_pContainerDropSource = 0;
00066 m_pContainerDropReceived = 0;
00067 m_pContextMenuContainer = 0;
00068 m_pFocusedContainer = 0;
00069 m_pToolBarOverlayLabel = 0;
00070
00071 m_pUpdateCaptionsTimer = new QTimer( this );
00072 connect( m_pUpdateCaptionsTimer, SIGNAL(timeout()), this, SLOT(slotUpdateCaptions()) );
00073
00074 setMinimumSize( 400, 400 );
00075
00076 DocManager::self(this);
00077 ItemInterface::self(this);
00078
00079 setupTabWidget();
00080 setupToolDocks();
00081 setupActions();
00082 setupView();
00083 readProperties( KGlobal::config() );
00084
00085
00086 }
00087
00088
00089 KTechlab::~KTechlab()
00090 {
00091 fileMetaInfo()->saveAllMetaInfo();
00092
00093 delete fileMetaInfo();
00094 delete itemLibrary();
00095 delete subcircuits();
00096 }
00097
00098
00099 void KTechlab::show()
00100 {
00101 KateMDI::MainWindow::show();
00102 m_bIsShown = true;
00103 }
00104
00105
00106 void KTechlab::load( const KURL & url )
00107 {
00108 if ( url.url().endsWith( ".ktechlab", false ) )
00109 {
00110
00111
00112
00113 ProjectManager::self()->slotOpenProject( url );
00114 return;
00115 }
00116
00117
00118 QString target;
00119
00120
00121
00122
00123
00124 if ( !KIO::NetAccess::download( url, target, this ) )
00125 {
00126
00127
00128 KMessageBox::error(this, KIO::NetAccess::lastErrorString());
00129
00130 return;
00131 }
00132
00133 addRecentFile(url);
00134
00135
00136 setCaption( url.prettyURL() );
00137
00138
00139 DocManager::self()->openURL( target );
00140
00141
00142 KIO::NetAccess::removeTempFile( target );
00143 }
00144
00145
00146 QStringList KTechlab::recentFiles()
00147 {
00148 return m_recentFiles->items();
00149 }
00150
00151
00152 void KTechlab::setupToolDocks()
00153 {
00154 #if defined(KDE_MAKE_VERSION)
00155 # if KDE_VERSION >= KDE_MAKE_VERSION(3,3,0)
00156 setToolViewStyle( KMultiTabBar::KDEV3ICON );
00157 # endif
00158 #endif
00159
00160 QPixmap pm;
00161 KIconLoader * loader = KGlobal::iconLoader();
00162 KateMDI::ToolView * tv = 0;
00163
00164 tv = createToolView( ProjectManager::toolViewIdentifier(),
00165 KMultiTabBar::Left,
00166 loader->loadIcon( "attach", KIcon::Small ),
00167 i18n("Project") );
00168 ProjectManager::self( this, tv );
00169
00170 pm.load( locate( "appdata", "icons/circuit.png" ) );
00171 tv = createToolView( ComponentSelector::toolViewIdentifier(),
00172 KMultiTabBar::Left,
00173 pm,
00174 i18n("Components") );
00175 ComponentSelector::self(tv);
00176
00177
00178 subcircuits();
00179 Subcircuits::loadSubcircuits();
00180
00181 pm.load( locate( "appdata", "icons/flowcode.png" ) );
00182 tv = createToolView( FlowPartSelector::toolViewIdentifier(),
00183 KMultiTabBar::Left,
00184 pm,
00185 i18n("Flow Parts") );
00186 FlowPartSelector::self(tv);
00187
00188 #ifdef MECHANICS
00189 pm.load( locate( "appdata", "icons/mechanics.png" ) );
00190 tv = createToolView( MechanicsSelector::toolViewIdentifier(),
00191 KMultiTabBar::Left,
00192 pm,
00193 i18n("Mechanics") );
00194 MechanicsSelector::self(tv);
00195 #endif
00196
00197 pm.load( locate( "appdata", "icons/item.png" ) );
00198 tv = createToolView( ItemEditor::toolViewIdentifier(),
00199 KMultiTabBar::Right,
00200 pm,
00201 i18n("Item Editor") );
00202 ItemEditor::self(tv);
00203
00204 tv = createToolView( ContextHelp::toolViewIdentifier(),
00205 KMultiTabBar::Right,
00206 loader->loadIcon( "contents", KIcon::Small ),
00207 i18n("Context Help") );
00208 ContextHelp::self(tv);
00209
00210 tv = createToolView( LanguageManager::toolViewIdentifier(),
00211 KMultiTabBar::Bottom,
00212 loader->loadIcon( "log", KIcon::Small ),
00213 i18n("Messages") );
00214 LanguageManager::self( tv, this );
00215
00216 #ifndef NO_GPSIM
00217 tv = createToolView( SymbolViewer::toolViewIdentifier(),
00218 KMultiTabBar::Right,
00219 loader->loadIcon( "blockdevice", KIcon::Small ),
00220 i18n("Symbol Viewer") );
00221 SymbolViewer::self(tv);
00222 #endif
00223
00224 addOscilloscopeAsToolView(this);
00225 }
00226
00227
00228 void KTechlab::addWindow( ViewContainer * vc )
00229 {
00230 if ( vc && !m_viewContainerList.contains(vc) )
00231 {
00232 m_viewContainerList << vc;
00233 connect( vc, SIGNAL(destroyed(QObject* )), this, SLOT(slotViewContainerDestroyed(QObject* )) );
00234 }
00235
00236 m_viewContainerList.remove((ViewContainer*)0);
00237 slotUpdateTabWidget();
00238 slotDocModifiedChanged();
00239 }
00240
00241
00242 void KTechlab::setupView()
00243 {
00244 setAcceptDrops(true);
00245 setStandardToolBarMenuEnabled(true);
00246 setXMLFile("ktechlabui.rc");
00247 createShellGUI(true);
00248 action("newfile_popup")->plug( toolBar("mainToolBar"), 0 );
00249 action("file_new")->unplug( toolBar("mainToolBar") );
00250 statusBar()->show();
00251 }
00252
00253
00254 void KTechlab::overlayToolBarScreenshot()
00255 {
00256 if ( !m_pToolBarOverlayLabel )
00257 {
00258 m_pToolBarOverlayLabel = new QLabel( 0, 0, WStyle_StaysOnTop | WStyle_Customize | WStyle_NoBorder | WNoAutoErase | WType_Popup );
00259 m_pToolBarOverlayLabel->hide();
00260 m_pToolBarOverlayLabel->setBackgroundMode( NoBackground );
00261 }
00262
00263 if ( !m_bIsShown )
00264 {
00265
00266
00267 return;
00268 }
00269
00270 if ( m_pToolBarOverlayLabel->isShown() )
00271 {
00272
00273
00274
00275 return;
00276 }
00277
00278 QPtrListIterator<KToolBar> toolBarIterator();
00279
00280
00281
00282
00283 KToolBar * toolsWidget = static_cast<KToolBar*>(child( "toolsToolBar", "KToolBar" ));
00284 KToolBar * debugWidget = static_cast<KToolBar*>(child( "debugTB", "KToolBar" ));
00285
00286 if ( !toolsWidget && !debugWidget )
00287 return;
00288
00289 QWidget * parent = static_cast<QWidget*>(toolsWidget ? toolsWidget->parent() : debugWidget->parent());
00290
00291 QRect grabRect;
00292
00293
00294
00295 if ( toolsWidget && toolsWidget->height() <= 128 )
00296 grabRect |= toolsWidget->geometry();
00297 if ( debugWidget && debugWidget->height() <= 128 )
00298 grabRect |= debugWidget->geometry();
00299
00300 if ( !grabRect.isValid() )
00301 return;
00302
00303 QPixmap shot = QPixmap::grabWidget( parent, grabRect.x(), grabRect.y(), grabRect.width(), grabRect.height() );
00304
00305 m_pToolBarOverlayLabel->move( parent->mapToGlobal( grabRect.topLeft() ) );
00306 m_pToolBarOverlayLabel->setFixedSize( grabRect.size() );
00307 m_pToolBarOverlayLabel->setPixmap( shot );
00308 m_pToolBarOverlayLabel->show();
00309
00310 QTimer::singleShot( 100, this, SLOT( hideToolBarOverlay() ) );
00311 }
00312
00313
00314 void KTechlab::hideToolBarOverlay()
00315 {
00316 if ( !m_pToolBarOverlayLabel )
00317 return;
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327 m_pToolBarOverlayLabel->hide();
00328 }
00329
00330
00331 void KTechlab::addNoRemoveGUIClient( KXMLGUIClient * client )
00332 {
00333 if ( client && !m_noRemoveGUIClients.contains( client ) )
00334 m_noRemoveGUIClients << client;
00335 }
00336
00337
00338 void KTechlab::removeGUIClients()
00339 {
00340 QValueList<KXMLGUIClient*> clientsToRemove;
00341
00342 QPtrList<KXMLGUIClient> clients = factory()->clients();
00343 for ( KXMLGUIClient * client = clients.first(); client; client = clients.next() )
00344 {
00345 if ( client && client != this && !m_noRemoveGUIClients.contains( client ) )
00346 clientsToRemove << client;
00347 }
00348
00349 if ( clients.isEmpty() )
00350 return;
00351
00352 overlayToolBarScreenshot();
00353
00354 QValueList<KXMLGUIClient*>::iterator end = clientsToRemove.end();
00355 for ( QValueList<KXMLGUIClient*>::iterator it = clientsToRemove.begin(); it != end; ++it )
00356 factory()->removeClient(*it);
00357 }
00358
00359
00360 void KTechlab::setupTabWidget()
00361 {
00362 m_pViewContainerTabWidget = new KTabWidget(centralWidget());
00363 connect( tabWidget(), SIGNAL(currentChanged(QWidget* )), this, SLOT(slotViewContainerActivated(QWidget* )) );
00364 connect( tabWidget(), SIGNAL(testCanDecode(const QDragMoveEvent*, bool& )), this, SLOT(slotTabDragEvent(const QDragMoveEvent*, bool& )) );
00365 connect( tabWidget(), SIGNAL(initiateDrag(QWidget* )), this, SLOT(slotTabDragInitiate(QWidget* )) );
00366 connect( tabWidget(), SIGNAL(receivedDropEvent(QDropEvent* )), this, SLOT(slotTabReceivedDropEvent(QDropEvent* )) );
00367 connect( tabWidget(), SIGNAL(receivedDropEvent(QWidget*, QDropEvent* )), this, SLOT(slotTabReceivedDropEvent(QWidget*, QDropEvent* )) );
00368
00369 KConfig *config = kapp->config();
00370 config->setGroup("UI");
00371
00372 bool CloseOnHover = config->readBoolEntry( "CloseOnHover", false );
00373 tabWidget()->setHoverCloseButton( CloseOnHover );
00374
00375 bool CloseOnHoverDelay = config->readBoolEntry( "CloseOnHoverDelay", false );
00376 tabWidget()->setHoverCloseButtonDelayed( CloseOnHoverDelay );
00377
00378
00379
00380
00381 if (config->readBoolEntry( "ShowCloseTabsButton", true ))
00382 {
00383 QToolButton *but = new QToolButton(tabWidget());
00384 but->setIconSet(SmallIcon("tab_remove"));
00385 but->adjustSize();
00386 but->hide();
00387 connect( but, SIGNAL(clicked()), this, SLOT(slotViewContainerClose()) );
00388 tabWidget()->setCornerWidget(but, TopRight);
00389 }
00390
00391
00392 connect(tabWidget(), SIGNAL(contextMenu(QWidget*,const QPoint &)), this, SLOT(slotTabContext(QWidget*,const QPoint &)));
00393
00394 }
00395
00396
00397 void KTechlab::slotUpdateTabWidget()
00398 {
00399 m_viewContainerList.remove( (ViewContainer*)0 );
00400
00401 bool noWindows = m_viewContainerList.isEmpty();
00402
00403 if ( QWidget * button = tabWidget()->cornerWidget(TopRight) )
00404 button->setHidden( noWindows );
00405
00406 if ( noWindows )
00407 setCaption( 0 );
00408 }
00409
00410
00411 void KTechlab::setupActions()
00412 {
00413 KActionCollection *ac = actionCollection();
00414
00415 KStdAction::openNew( this, SLOT(slotFileNew()), ac );
00416 KStdAction::open( this, SLOT(slotFileOpen()), ac );
00417 KStdAction::save( this, SLOT(slotFileSave()), ac );
00418 KStdAction::saveAs( this, SLOT(slotFileSaveAs()), ac );
00419 KStdAction::close( this, SLOT(slotViewClose()), ac );
00420 KStdAction::print( this, SLOT(slotFilePrint()), ac );
00421 KStdAction::quit( this, SLOT(slotFileQuit()), ac );
00422 KStdAction::undo( this, SLOT(slotEditUndo()), ac );
00423 KStdAction::redo( this, SLOT(slotEditRedo()), ac );
00424 KStdAction::cut( this, SLOT(slotEditCut()), ac );
00425 KStdAction::copy( this, SLOT(slotEditCopy()), ac );
00426 KStdAction::paste( this, SLOT(slotEditPaste()), ac );
00427 KStdAction::keyBindings( this, SLOT(slotOptionsConfigureKeys()), ac );
00428 KStdAction::configureToolbars( this, SLOT(slotOptionsConfigureToolbars()), ac );
00429 KStdAction::preferences( this, SLOT(slotOptionsPreferences()), ac );
00430
00431
00432 KToolBarPopupAction *p = new KToolBarPopupAction( i18n("&New"), "filenew", KStdAccel::shortcut(KStdAccel::New), this, SLOT(slotFileNew()), ac, "newfile_popup" );
00433 p->popupMenu()->insertTitle( i18n("New File") );
00434 (new KAction( i18n("Assembly"), "source", 0, this, SLOT(slotFileNewAssembly()), ac, "newfile_asm" ))->plug( p->popupMenu() );
00435 (new KAction( i18n("C source"), "source_c", 0, this, SLOT(slotFileNewC()), ac, "newfile_c" ))->plug( p->popupMenu() );
00436 (new KAction( i18n("Circuit"), "ktechlab_circuit", 0, this, SLOT(slotFileNewCircuit()), ac, "newfile_circuit" ))->plug( p->popupMenu() );
00437 (new KAction( i18n("FlowCode"), "ktechlab_flowcode", 0, this, SLOT(slotFileNewFlowCode()), ac, "newfile_flowcode" ))->plug( p->popupMenu() );
00438 #ifdef MECHANICS
00439 (new KAction( i18n("Mechanics"), "ktechlab_mechanics", 0, this, SLOT(slotFileNewMechanics()), ac, "newfile_mechanics" ))->plug( p->popupMenu() );
00440 #endif
00441 (new KAction( "Microbe", "ktechlab_microbe", 0, this, SLOT(slotFileNewMicrobe()), ac, "newfile_microbe" ))->plug( p->popupMenu() );
00442
00443
00444
00445
00446 m_recentFiles = new RecentFilesAction( "Recent Files", i18n("Open Recent"), this, SLOT(load(const KURL &)), ac, "file_open_recent" );
00447 m_statusbarAction = KStdAction::showStatusbar( this, SLOT(slotOptionsShowStatusbar()), ac );
00448
00449
00450 ProjectManager *pm = ProjectManager::self(this);
00451 new KAction( i18n("New Project.."), "window_new", 0, pm, SLOT(slotNewProject()), ac, "project_new" );
00452 new KAction( i18n("Open Project..."), "project_open", 0, pm, SLOT(slotOpenProject()), ac, "project_open" );
00453
00454 m_recentProjects = new RecentFilesAction( "Recent Projects", i18n("Open &Recent Project..."), ProjectManager::self(), SLOT(slotOpenProject(const KURL&)), ac, "project_open_recent" );
00455 new KAction( i18n("Export to Makefile..."), "fileexport", 0, pm, SLOT(slotExportToMakefile()), ac, "project_export_makefile" );
00456 new KAction( i18n("Create Subproject..."), 0, 0, pm, SLOT(slotCreateSubproject()), ac, "project_create_subproject" );
00457 new KAction( i18n("Add Existing File..."), "fileopen", 0, pm, SLOT(slotAddFile()), ac, "project_add_existing_file" );
00458 new KAction( i18n("Add Current File..."), "fileimport", 0, pm, SLOT(slotAddCurrentFile()), ac, "project_add_current_file" );
00459
00460 new KAction( i18n("Close Project"), "fileclose", 0, pm, SLOT(slotCloseProject()), ac, "project_close" );
00461 new KAction( i18n("Remove from Project"), "editdelete", 0, pm, SLOT(slotRemoveSelected()), ac, "project_remove_selected" );
00462 new KAction( i18n("Insert Existing File..."), "fileopen", 0, pm, SLOT(slotSubprojectAddExistingFile()), ac, "subproject_add_existing_file" );
00463 new KAction( i18n("Insert Current File..."), "fileimport", 0, pm, SLOT(slotSubprojectAddCurrentFile()),ac, "subproject_add_current_file" );
00464 new KAction( i18n("Linker Options..."), "configure", 0, pm, SLOT(slotSubprojectLinkerOptions()), ac, "project_item_linker_options" );
00465 new KAction( i18n("Build..."), "launch", 0, pm, SLOT(slotItemBuild()), ac, "project_item_build" );
00466 new KAction( i18n("Upload..."), "convert_to_pic", 0, pm, SLOT(slotItemUpload()), ac, "project_item_upload" );
00467 new KAction( i18n("Processing Options..."), "configure", 0, pm, SLOT(slotItemProcessingOptions()), ac, "project_item_processing_options" );
00468
00469
00470 new KAction( i18n("Split View Left/Right"), "view_right", Qt::CTRL|Qt::SHIFT|Qt::Key_L, this, SLOT(slotViewSplitLeftRight()), ac, "view_split_leftright" );
00471 new KAction( i18n("Split View Top/Bottom"), "view_bottom", Qt::CTRL|Qt::SHIFT|Qt::Key_T, this, SLOT(slotViewSplitTopBottom()), ac, "view_split_topbottom" );
00472
00473 KToggleAction * ta = new KToggleAction( i18n("Run Simulation"), "player_play", Qt::Key_F10, 0, 0, ac, "simulation_run" );
00474 ta->setChecked(true);
00475 connect( ta, SIGNAL(toggled(bool )), Simulator::self(), SLOT(slotSetSimulating(bool )) );
00476 #if defined(KDE_MAKE_VERSION)
00477 # if KDE_VERSION >= KDE_MAKE_VERSION(3,3,0)
00478 ta->setCheckedState( KGuiItem( i18n("Pause Simulation"), "player_pause", 0 ) );
00479 # endif
00480 #endif
00481
00482
00483 ProjectManager::self(this)->updateActions();
00484
00485 DocManager::self(this)->disableContextActions();
00486 }
00487
00488
00489 void KTechlab::slotViewContainerActivated( QWidget * viewContainer )
00490 {
00491 if (m_pFocusedContainer)
00492 m_pFocusedContainer->setUnfocused();
00493
00494 m_pFocusedContainer = dynamic_cast<ViewContainer*>(viewContainer);
00495 if ( !m_pFocusedContainer )
00496 return;
00497
00498 m_pFocusedContainer->setFocused();
00499 }
00500
00501
00502 void KTechlab::slotViewContainerDestroyed( QObject * object )
00503 {
00504 m_viewContainerList.remove( static_cast<ViewContainer*>(object) );
00505 m_viewContainerList.remove( (ViewContainer*)0 );
00506 slotUpdateTabWidget();
00507 }
00508
00509
00510 void KTechlab::slotTabDragEvent( const QDragMoveEvent *e, bool &accept )
00511 {
00512
00513
00514 Q_UNUSED(e);
00515 accept = true;
00516 }
00517
00518
00519 void KTechlab::slotTabDragInitiate( QWidget *widget )
00520 {
00521 ViewContainer *viewContainer = dynamic_cast<ViewContainer*>(widget);
00522 if (!viewContainer)
00523 return;
00524 QDragObject *dragObject = new ViewContainerDrag(viewContainer);
00525 dragObject->drag();
00526 }
00527
00528
00529 void KTechlab::slotTabReceivedDropEvent( QDropEvent *e )
00530 {
00531 if (!e)
00532 return;
00533 ViewContainer *viewContainerSource = dynamic_cast<ViewContainer*>(e->source());
00534 if (!viewContainerSource)
00535 {
00536 e->ignore();
00537 return;
00538 }
00539 e->accept(true);
00540 viewContainerSource->duplicateViewContainer();
00541 }
00542
00543
00544 void KTechlab::slotTabReceivedDropEvent( QWidget *widget, QDropEvent *e )
00545 {
00546 if (!e)
00547 return;
00548 m_pContainerDropSource = dynamic_cast<ViewContainer*>(e->source());
00549 m_pContainerDropReceived = dynamic_cast<ViewContainer*>(widget);
00550 if ( !m_pContainerDropSource || !m_pContainerDropReceived || (m_pContainerDropSource == m_pContainerDropReceived) )
00551 {
00552 e->ignore();
00553 return;
00554 }
00555 e->accept(true);
00556
00557 KPopupMenu dropMenu;
00558 dropMenu.insertItem( KGlobal::iconLoader()->loadIcon( "goto", KIcon::Small ), i18n("&Insert Into"), 0 );
00559 dropMenu.insertItem( KGlobal::iconLoader()->loadIcon( "editcopy", KIcon::Small ), i18n("&Copy Into"), 1 );
00560 dropMenu.insertSeparator();
00561 dropMenu.insertItem( KGlobal::iconLoader()->loadIcon( "stop", KIcon::Small ), i18n("C&ancel"), 2 );
00562
00563 connect( &dropMenu, SIGNAL(activated(int)), this, SLOT(slotDragContextActivated(int)) );
00564
00565 dropMenu.exec( QCursor::pos() );
00566 }
00567
00568
00569 void KTechlab::slotDragContextActivated( int id )
00570 {
00571 if ( !m_pContainerDropSource || !m_pContainerDropReceived )
00572 return;
00573
00574 switch (id)
00575 {
00576 case 0:
00577 m_pContainerDropSource->copyViewContainerIntoExisting(m_pContainerDropReceived);
00578 m_pContainerDropSource->closeViewContainer();
00579 break;
00580 case 1:
00581 m_pContainerDropSource->copyViewContainerIntoExisting(m_pContainerDropReceived);
00582 break;
00583 case 2:
00584 default:
00585 break;
00586 }
00587 }
00588
00589
00590 KAction * KTechlab::action( const QString & name ) const
00591 {
00592 KAction * action = actionCollection()->action(name);
00593 if ( !action )
00594 kdError() << k_funcinfo << "No such action: " << name << endl;
00595 return action;
00596 }
00597
00598
00599 void KTechlab::saveProperties( KConfig *conf )
00600 {
00601
00602 conf->setGroup("UI");
00603 conf->writeEntry( "Width", width() );
00604 conf->writeEntry( "Height", height() );
00605 conf->writeEntry( "WinState", KWin::windowInfo( winId(), NET::WMState ).state() );
00606
00607 #ifndef NO_GPSIM
00608 SymbolViewer::self()->saveProperties( conf );
00609 #endif
00610
00611 if ( ProjectManager::self()->currentProject() )
00612 {
00613 conf->setGroup("Project");
00614 conf->writePathEntry( "Open", ProjectManager::self()->currentProject()->url().prettyURL() );
00615 }
00616 else
00617 conf->deleteGroup("Project");
00618
00619
00620
00621 const QStringList groupList = conf->groupList();
00622 const QStringList::const_iterator groupListEnd = groupList.end();
00623 for ( QStringList::const_iterator it = groupList.begin(); it != groupListEnd; ++it )
00624 {
00625 if ( (*it).startsWith("ViewContainer") )
00626 conf->deleteGroup(*it);
00627 }
00628
00629 uint viewContainerId = 1;
00630 const ViewContainerList::iterator vcEnd = m_viewContainerList.end();
00631 for ( ViewContainerList::iterator it = m_viewContainerList.begin(); it != vcEnd; ++it )
00632 {
00633 if ( !(*it) || !(*it)->canSaveUsefulStateInfo() )
00634 continue;
00635
00636
00637
00638 const QString id = QString::number(viewContainerId++).rightJustify( 4, '0' );
00639
00640 conf->setGroup( "ViewContainer " + id );
00641 (*it)->saveState(conf);
00642 }
00643
00644
00645 saveSession( conf, "KateMDI" );
00646
00647 conf->setGroup("KateMDI");
00648 int scnum = QApplication::desktop()->screenNumber(parentWidget());
00649 QRect desk = QApplication::desktop()->screenGeometry(scnum);
00650 conf->deleteEntry( QString::fromLatin1("Width %1").arg(desk.width()) );
00651 conf->deleteEntry( QString::fromLatin1("Height %1").arg(desk.height()) );
00652
00653 conf->sync();
00654 }
00655
00656
00657 void KTechlab::readProperties( KConfig *conf )
00658 {
00659 startRestore( conf, "KateMDI" );
00660
00661 m_recentFiles->loadEntries();
00662 m_recentProjects->loadEntries();
00663
00664
00665 if ( KTLConfig::restoreDocumentsOnStartup() )
00666 {
00667
00668
00669 qApp->processEvents();
00670
00671 const QStringList groupList = conf->groupList();
00672 const QStringList::const_iterator groupListEnd = groupList.end();
00673 for ( QStringList::const_iterator it = groupList.begin(); it != groupListEnd; ++it )
00674 {
00675 if ( (*it).startsWith("ViewContainer") )
00676 {
00677 ViewContainer *viewContainer = new ViewContainer( *it, this );
00678
00679 conf->setGroup(*it);
00680 viewContainer->restoreState( conf, *it );
00681
00682 addWindow( viewContainer );
00683 }
00684 }
00685 }
00686
00687
00688 conf->setGroup("Project");
00689 if ( conf->readPathEntry("Open") != QString::null )
00690 ProjectManager::self()->slotOpenProject( KURL( conf->readPathEntry("Open") ) );
00691
00692 #ifndef NO_GPSIM
00693 SymbolViewer::self()->readProperties( conf );
00694 #endif
00695
00696 finishRestore();
00697
00698
00699 conf->setGroup("UI");
00700 resize( conf->readNumEntry( "Width", 800 ), conf->readNumEntry( "Height", 500 ) );
00701 KWin::setState( winId(), conf->readLongNumEntry( "WinState", NET::Max ) );
00702 }
00703
00704
00705 void KTechlab::dragEnterEvent(QDragEnterEvent *event)
00706 {
00707
00708 event->accept(KURLDrag::canDecode(event));
00709 }
00710
00711
00712 void KTechlab::dropEvent(QDropEvent *event)
00713 {
00714
00715
00716
00717 KURL::List urls;
00718
00719
00720 if (KURLDrag::decode(event, urls) && !urls.isEmpty())
00721 {
00722
00723 const KURL &url = urls.first();
00724
00725
00726 load(url);
00727 }
00728 }
00729
00730
00731 void KTechlab::slotOptionsShowStatusbar()
00732 {
00733
00734
00735 if (m_statusbarAction->isChecked())
00736 statusBar()->show();
00737 else
00738 statusBar()->hide();
00739 }
00740
00741
00742 void KTechlab::slotOptionsConfigureKeys()
00743 {
00744
00745 KKeyDialog::configure( actionCollection(), this, true );
00746 }
00747
00748
00749 void KTechlab::slotOptionsConfigureToolbars()
00750 {
00751 KEditToolbar *dlg = new KEditToolbar(guiFactory());
00752
00753 if (dlg->exec())
00754 {
00755 createShellGUI( false );
00756 createShellGUI( true );
00757 }
00758
00759 delete dlg;
00760 }
00761
00762
00763 void KTechlab::slotOptionsPreferences()
00764 {
00765
00766
00767
00768 if ( KConfigDialog::showDialog( "settings" ) )
00769 return;
00770
00771
00772 SettingsDlg* dialog = new SettingsDlg( this, "settings", KTLConfig::self() );
00773
00774
00775
00776 connect( dialog, SIGNAL(settingsChanged()), this, SLOT(slotUpdateConfiguration()) );
00777 dialog->show();
00778 }
00779
00780
00781 void KTechlab::slotUpdateConfiguration()
00782 {
00783 emit configurationChanged();
00784 }
00785
00786
00787 void KTechlab::slotChangeStatusbar( const QString & text )
00788 {
00789
00790 if ( m_lastStatusBarMessage == text )
00791 return;
00792
00793 statusBar()->message(text);
00794 m_lastStatusBarMessage = text;
00795 }
00796
00797
00798 void KTechlab::slotTabContext( QWidget* widget,const QPoint & pos )
00799 {
00800
00801
00802 KPopupMenu *tabMenu = new KPopupMenu;
00803 tabMenu->insertTitle( (dynamic_cast<ViewContainer*>(widget))->caption() );
00804
00805
00806 m_pContextMenuContainer = 0;
00807
00808 m_viewContainerList.remove((ViewContainer*)0);
00809
00810 const ViewContainerList::iterator vcEnd = m_viewContainerList.end();
00811 for ( ViewContainerList::iterator it = m_viewContainerList.begin(); it != vcEnd; ++it ) {
00812 ViewContainer * viewContainer = *it;
00813 if ( viewContainer == widget ) {
00814 m_pContextMenuContainer = viewContainer;
00815
00816 tabMenu->insertItem( i18n("Close"), 0 );
00817
00818 View *view = (viewContainer->viewCount() == 1) ? viewContainer->activeView() : 0;
00819
00820 if ( view && view->document()->isModified() )
00821 tabMenu->insertItem( i18n("Save"), 1 );
00822
00823 if ( view && !view->document()->url().isEmpty() )
00824 tabMenu->insertItem( i18n("Reload"), 2 );
00825
00826 if ( m_viewContainerList.count() > 1 )
00827 tabMenu->insertItem( i18n("Close All Others"), 4 );
00828
00829 }
00830 }
00831
00832 connect( tabMenu, SIGNAL( activated(int) ), this, SLOT(slotTabContextActivated(int)) );
00833
00834 tabMenu->exec(pos);
00835 delete tabMenu;
00836 }
00837
00838 void KTechlab::slotTabContextActivated( int id )
00839 {
00840
00841
00842 if( !m_pContextMenuContainer ) return;
00843
00844 View *view = m_pContextMenuContainer->activeView();
00845 if (!view) return;
00846
00847 QGuardedPtr<Document> document = view->document();
00848
00849 switch(id)
00850 {
00851 case 0:
00852 m_pContextMenuContainer->closeViewContainer();
00853 break;
00854 case 1:
00855 document->fileSave();
00856 break;
00857 case 2:
00858 {
00859 KURL url = document->url();
00860 if ( document->fileClose() ) {
00861 delete document;
00862 DocManager::self()->openURL(url);
00863 }
00864 break;
00865 }
00866 case 4:
00867 {
00868 const ViewContainerList::iterator vcEnd = m_viewContainerList.end();
00869 for ( ViewContainerList::iterator it = m_viewContainerList.begin(); it != vcEnd; ++it )
00870 {
00871 ViewContainer *viewContainer = *it;
00872 if ( viewContainer && viewContainer != m_pContextMenuContainer )
00873 {
00874 if ( !viewContainer->closeViewContainer() )
00875 return;
00876 }
00877 }
00878 break;
00879 }
00880 default:
00881 break;
00882 }
00883 }
00884
00885
00886
00887 void KTechlab::slotFileNewAssembly()
00888 {
00889 TextDocument *document = DocManager::self()->createTextDocument();
00890 if (document)
00891 document->slotInitLanguage( TextDocument::ct_asm );
00892 }
00893 void KTechlab::slotFileNewMicrobe()
00894 {
00895 TextDocument *document = DocManager::self()->createTextDocument();
00896 if (document)
00897 document->slotInitLanguage( TextDocument::ct_microbe );
00898 }
00899 void KTechlab::slotFileNewC()
00900 {
00901 TextDocument *document = DocManager::self()->createTextDocument();
00902 if (document)
00903 document->slotInitLanguage( TextDocument::ct_c );
00904 }
00905 void KTechlab::slotFileNewCircuit()
00906 {
00907 DocManager::self()->createCircuitDocument();
00908 }
00909 void KTechlab::slotFileNewFlowCode()
00910 {
00911 slotFileNew();
00912 }
00913 void KTechlab::slotFileNewMechanics()
00914 {
00915 DocManager::self()->createMechanicsDocument();
00916 }
00917
00918 void KTechlab::slotFileNew()
00919 {
00920 NewFileDlg *newFileDlg = new NewFileDlg(this);
00921
00922 newFileDlg->exec();
00923
00924 bool addToProject = newFileDlg->addToProject();
00925 bool accepted = newFileDlg->accepted();
00926 int finalType = newFileDlg->fileType();
00927 QString microID = newFileDlg->microID();
00928 int codeType = newFileDlg->codeType();
00929
00930 delete newFileDlg;
00931 if (!accepted)
00932 return;
00933
00934 Document *created = 0;
00935
00936 if ( finalType == Document::dt_circuit )
00937 created = DocManager::self()->createCircuitDocument();
00938
00939 else if ( finalType == Document::dt_flowcode )
00940 {
00941 FlowCodeDocument * fcd = DocManager::self()->createFlowCodeDocument();
00942 fcd->setPicType(microID);
00943 created = fcd;
00944 }
00945
00946 else if ( finalType == Document::dt_mechanics )
00947 created = DocManager::self()->createMechanicsDocument();
00948
00949 else
00950 {
00951
00952 TextDocument * textDocument = DocManager::self()->createTextDocument();
00953
00954 if (textDocument)
00955 textDocument->slotInitLanguage( (TextDocument::CodeType)codeType );
00956
00957 created = textDocument;
00958 }
00959
00960 if ( created && addToProject )
00961 created->setAddToProjectOnSave(true);
00962 }
00963
00964 void KTechlab::slotFileOpen()
00965 {
00966
00967
00968
00969
00970
00971 KURL::List urls = getFileURLs();
00972 const KURL::List::iterator end = urls.end();
00973 for ( KURL::List::iterator it = urls.begin(); it != end; ++ it)
00974 load(*it);
00975 }
00976
00977 void KTechlab::addRecentFile( const KURL &url )
00978 {
00979 m_recentFiles->addURL( url );
00980 emit recentFileAdded(url);
00981 }
00982
00983
00984 KURL::List KTechlab::getFileURLs()
00985 {
00986 return KFileDialog::getOpenURLs(
00987 QString::null,
00988 "*|All Files\n"
00989 "*.asm *.src *.inc|Assembly Code (*.asm, *.src, *.inc)\n"
00990 "*.hex|Intel Hex (*.hex)\n"
00991 "*.circuit|Circuit (*.circuit)\n"
00992 "*.flowcode|FlowCode (*.flowcode)\n"
00993 "*.basic *.microbe|Microbe (*.microbe, *.basic)\n"
00994 "*.mechanics|Mechanics (*.mechanics)\n",
00995 0,
00996 i18n("Open Location") );
00997 }
00998
00999
01000 void KTechlab::slotDocModifiedChanged()
01001 {
01002
01003 KIconLoader *loader = KGlobal::iconLoader();
01004 const ViewContainerList::iterator vcEnd = m_viewContainerList.end();
01005 for ( ViewContainerList::iterator it = m_viewContainerList.begin(); it != vcEnd; ++it )
01006 {
01007 ViewContainer * vc = *it;
01008 if ( !vc || !vc->activeView() || !vc->activeView()->document() )
01009 continue;
01010
01011 QString iconName;
01012
01013 if ( vc->activeView()->document()->isModified() )
01014 iconName = "filesave";
01015
01016 else switch ( vc->activeView()->document()->type() )
01017 {
01018 case Document::dt_circuit:
01019 iconName = "ktechlab_circuit";
01020 break;
01021
01022 case Document::dt_flowcode:
01023 iconName = "ktechlab_flowcode";
01024 break;
01025
01026 case Document::dt_mechanics:
01027 iconName = "ktechlab_mechanics";
01028 break;
01029
01030 case Document::dt_text:
01031 iconName = "txt";
01032 break;
01033
01034 case Document::dt_pinMapEditor:
01035 break;
01036
01037 case Document::dt_none:
01038 iconName = "unknown";
01039 break;
01040 }
01041
01042 tabWidget()->setTabIconSet( vc, loader->loadIcon( iconName, KIcon::Small ) );
01043 }
01044
01045 }
01046
01047
01048 void KTechlab::requestUpdateCaptions()
01049 {
01050 m_pUpdateCaptionsTimer->start( 0, true );
01051 }
01052
01053
01054 void KTechlab::slotUpdateCaptions()
01055 {
01056
01057 Document *document = DocManager::self()->getFocusedDocument();
01058 QString newCaption;
01059 if ( document )
01060 {
01061 KURL url = document->url();
01062 if ( url.isEmpty() )
01063 newCaption = document->caption();
01064 else
01065 {
01066 if ( url.isLocalFile() && url.ref().isNull() && url.query().isNull() )
01067 newCaption = url.path();
01068 else
01069 newCaption = url.prettyURL();
01070 }
01071 }
01072 else
01073 newCaption = "";
01074
01075 if (newCaption != caption().remove(" - KTechlab"))
01076 setCaption(newCaption);
01077
01078
01079
01080
01081 emit needUpdateCaptions();
01082
01083 if ( document && document->activeView() && document->activeView()->viewContainer() )
01084 {
01085 document->activeView()->viewContainer()->updateCaption();
01086 }
01087
01088 }
01089
01090
01091 void KTechlab::slotDocUndoRedoChanged()
01092 {
01093 Document *document = DocManager::self()->getFocusedDocument();
01094 if (!document)
01095 return;
01096
01097 action("edit_undo")->setEnabled( document->isUndoAvailable() );
01098 action("edit_redo")->setEnabled( document->isRedoAvailable() );
01099 }
01100
01101 void KTechlab::slotFileSave()
01102 {
01103 Document *document = DocManager::self()->getFocusedDocument();
01104 if (document)
01105 document->fileSave();
01106 }
01107
01108 void KTechlab::slotFileSaveAs()
01109 {
01110 Document *document = DocManager::self()->getFocusedDocument();
01111 if (document)
01112 document->fileSaveAs();
01113 }
01114
01115 void KTechlab::slotFilePrint()
01116 {
01117 Document *document = DocManager::self()->getFocusedDocument();
01118 if (document)
01119 document->print();
01120 }
01121
01122
01123 bool KTechlab::queryClose()
01124 {
01125 saveProperties( KGlobal::config() );
01126
01127 if ( DocManager::self()->closeAll() && ProjectManager::self()->slotCloseProject() )
01128 {
01129 ViewContainerList::iterator end = m_viewContainerList.end();
01130 for ( ViewContainerList::iterator it = m_viewContainerList.begin(); it != end; ++it )
01131 {
01132 if ( *it )
01133 (*it)->setKTechlabDeleted();
01134 }
01135
01136 return true;
01137 }
01138
01139 return false;
01140 }
01141
01142 void KTechlab::slotFileQuit()
01143 {
01144
01145
01146 KMainWindow* w;
01147 if(memberList)
01148 {
01149 for( w=memberList->first(); w!=0; w=memberList->next() )
01150 {
01151
01152
01153 if( !w->close() ) break;
01154 }
01155 }
01156
01157 slotChangeStatusbar( i18n("Exiting...") );
01158 }
01159
01160 void KTechlab::slotEditUndo()
01161 {
01162 Document *document = DocManager::self()->getFocusedDocument();
01163 if (document)
01164 document->undo();
01165 }
01166
01167 void KTechlab::slotEditRedo()
01168 {
01169 Document *document = DocManager::self()->getFocusedDocument();
01170 if (document)
01171 document->redo();
01172 }
01173
01174 void KTechlab::slotEditCut()
01175 {
01176 Document *document = DocManager::self()->getFocusedDocument();
01177 if (document)
01178 document->cut();
01179 }
01180
01181 void KTechlab::slotEditCopy()
01182 {
01183 Document *document = DocManager::self()->getFocusedDocument();
01184 if (document)
01185 document->copy();
01186 }
01187
01188 void KTechlab::slotEditPaste()
01189 {
01190 Document *document = DocManager::self()->getFocusedDocument();
01191 if (document)
01192 document->paste();
01193 }
01194
01195 void KTechlab::slotViewContainerClose()
01196 {
01197 if (m_pFocusedContainer)
01198 m_pFocusedContainer->closeViewContainer();
01199 }
01200 void KTechlab::slotViewClose()
01201 {
01202 View *view = DocManager::self()->getFocusedView();
01203 if (view)
01204 view->closeView();
01205 }
01206 void KTechlab::slotViewSplitLeftRight()
01207 {
01208 View *view = DocManager::self()->getFocusedView();
01209 if (!view)
01210 return;
01211 ViewContainer *vc = view->viewContainer();
01212 uint vaId = vc->createViewArea( view->viewAreaId(), ViewArea::Right );
01213 view->document()->createView( vc, vaId );
01214 }
01215 void KTechlab::slotViewSplitTopBottom()
01216 {
01217 View *view = DocManager::self()->getFocusedView();
01218 if (!view)
01219 return;
01220 ViewContainer *vc = view->viewContainer();
01221 uint vaId = vc->createViewArea( view->viewAreaId(), ViewArea::Bottom );
01222 view->document()->createView( vc, vaId );
01223 }
01224
01225 #include "ktechlab.moc"