ktechlab.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2003-2005 by David Saxton                               *
00003  *   david@bluehaze.org                                                    *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
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 //      kdDebug() << "Constructor time: " << ct.elapsed() << endl;
00086 }
00087 
00088 
00089 KTechlab::~KTechlab()
00090 {
00091         fileMetaInfo()->saveAllMetaInfo();
00092         
00093         delete fileMetaInfo();
00094         delete itemLibrary(); // This better be the last time the item library is used!
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                 // This is a ktechlab project; it has to be handled separetly from a
00111                 // normal file.
00112                 
00113                 ProjectManager::self()->slotOpenProject( url );
00114                 return;
00115         }
00116         
00117         
00118         QString target;
00119         // the below code is what you should normally do.  in this
00120         // example case, we want the url to our own.  you probably
00121         // want to use this code instead for your app
00122         
00123         // download the contents
00124         if ( !KIO::NetAccess::download( url, target, this ) )
00125         {
00126                 // If the file could not be downloaded, for example does not
00127                 // exist on disk, NetAccess will tell us what error to use
00128                 KMessageBox::error(this, KIO::NetAccess::lastErrorString());
00129                 
00130                 return;
00131         }
00132         
00133         addRecentFile(url);
00134         
00135         // set our caption
00136         setCaption( url.prettyURL() );
00137         
00138         // load in the file (target is always local)
00139         DocManager::self()->openURL( target );
00140         
00141         // and remove the temp file
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         // Create an instance of the subcircuits interface, now that we have created the component selector
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                 // The window isn't visible yet, so there's nothing to overlay (and if we tried,
00266                 // it would appear as a strange floating toolbar).
00267                 return;
00268         }
00269         
00270         if ( m_pToolBarOverlayLabel->isShown() )
00271         {
00272                 // This is to avoid successive calls to removeGUIClient when we have
00273                 // already popped it up for the first call, and don't want to take
00274                 // another screenshot (as that would be without the toolbar).
00275                 return;
00276         }
00277         
00278         QPtrListIterator<KToolBar> toolBarIterator();
00279         
00280 //      QWidget * toolsWidget = toolBar( "toolsToolBar" );
00281 //      QWidget * debugWidget = toolBar( "debugTB" );
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         // 128 is a sanity check (widget can do strange things when being destroyed)
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 //      QWidget * hiddenWidget = toolBar( "toolsToolBar" );
00320 //      if ( !hiddenWidget )
00321 //              return;
00322         
00323 //      hiddenWidget->setBackgroundMode( NoBackground );
00324 //      hiddenWidget->setWFlags( WNoAutoErase ); 
00325 //      hiddenWidget->setUpdatesEnabled( false );
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 //      bool openNewTabAfterCurrent = config->readBoolEntry( "OpenNewTabAfterCurrent", false );
00379 //      bool showTabIcons = config->readBoolEntry( "ShowTabIcons", true );
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 //      tabWidget()->setTabReorderingEnabled(true);
00391 //      connect(tabWidget(), SIGNAL(movedTab(int, int)), this, SLOT(tabMoved(int, int)));
00392         connect(tabWidget(), SIGNAL(contextMenu(QWidget*,const QPoint &)), this, SLOT(slotTabContext(QWidget*,const QPoint &)));
00393         //END Tab bar stuff
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         //BEGIN New file popup
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         //END New File popup
00443         
00444 
00445 //      m_recentFiles = KStdAction::openRecent( this, SLOT(load(const KURL&)), ac );
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         //BEGIN Project Actions
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 //      m_recentProjects = new KRecentFilesAction( i18n("Open &Recent Project..."), 0, ProjectManager::self(), SLOT(slotOpenProject(const KURL&)), ac, "project_open_recent" );
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 //      new KAction( i18n("Project Options"), "configure",                      0, pm, SLOT(slotProjectOptions()),                      ac, "project_options" );
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         //END Project Actions
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         // We can call slotCloseProject now that the actions have been created
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         // Hmm...this function doesn't actually seem to get called. Instead,
00513         // KTabBar just seems to go straight to slotTabDragInitiate.
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 //      dropMenu.exec(e->pos() + widget->pos() );
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         // Dumbass KMainWindow - can't handle my width/height correctly. Whoever thought of the "+1" hack anyway?!
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         //BEGIN Open Views State
00620         // Remvoe old entries describing the save state - we don't want a horrible mish-mash of saved states
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                 // To make sure the ViewContainers are restored in the right order, we must create them in alphabetical order,
00637                 // as KConfig stores them as such...
00638                 const QString id = QString::number(viewContainerId++).rightJustify( 4, '0' );
00639                         
00640                 conf->setGroup( "ViewContainer " + id );
00641                 (*it)->saveState(conf);
00642         }
00643         //END Open Views State
00644         
00645         saveSession( conf, "KateMDI" );
00646         // Piss off KMainWindow
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         //BEGIN Restore Open Views
00665         if ( KTLConfig::restoreDocumentsOnStartup() )
00666         {
00667                 // If we have a lot of views open from last time, then opening them will take a long time.
00668                 // So we want to enter the qt event loop to finish drawing the window et al before adding the views.
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         //END Restore Open Views
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         // Dumbass KMainWindow - can't handle my width/height correctly. Whoever thought of the "+1" hack anyway?!
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     // accept uri drops only
00708     event->accept(KURLDrag::canDecode(event));
00709 }
00710 
00711 
00712 void KTechlab::dropEvent(QDropEvent *event)
00713 {
00714     // this is a very simplistic implementation of a drop event.  we
00715     // will only accept a dropped URL.  the Qt dnd code can do *much*
00716     // much more, so please read the docs there
00717     KURL::List urls;
00718 
00719     // see if we can decode a URI.. if not, just ignore it
00720     if (KURLDrag::decode(event, urls) && !urls.isEmpty())
00721     {
00722         // okay, we have a URI.. process it
00723         const KURL &url = urls.first();
00724 
00725         // load in the file
00726         load(url);
00727     }
00728 }
00729 
00730 
00731 void KTechlab::slotOptionsShowStatusbar()
00732 {
00733     // this is all very cut and paste code for showing/hiding the
00734     // statusbar
00735     if (m_statusbarAction->isChecked())
00736         statusBar()->show();
00737     else
00738         statusBar()->hide();
00739 }
00740 
00741 
00742 void KTechlab::slotOptionsConfigureKeys()
00743 {
00744 //     KKeyDialog::configureKeys(actionCollection(), "ktechlabui.rc");
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         // An instance of your dialog could be already created and could be cached,
00766         // in which case you want to display the cached dialog instead of creating
00767         // another one
00768         if ( KConfigDialog::showDialog( "settings" ) )
00769                 return;
00770         
00771         // KConfigDialog didn't find an instance of this dialog, so lets create it:
00772         SettingsDlg* dialog = new SettingsDlg( this, "settings", KTLConfig::self() );
00773         
00774         // User edited the configuration - update your local copies of the
00775         // configuration data
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         // Avoid flicker by repeatedly displaying the same message, as QStatusBar does not check for this
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         // Shamelessly stolen from KDevelop...
00801         
00802         KPopupMenu *tabMenu = new KPopupMenu;
00803         tabMenu->insertTitle( (dynamic_cast<ViewContainer*>(widget))->caption() );
00804 
00805         //Find the document on whose tab the user clicked
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         // Shamelessly stolen from KDevelop...
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                 // Presumably a text document
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     // this slot is called whenever the File->Open menu is selected,
00967     // the Open shortcut is pressed (usually CTRL+O) or the Open toolbar
00968     // button is clicked
00969         
00970     // standard filedialog
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         //BEGIN Set tab icons
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         //END Set tab icons
01045 }
01046 
01047 
01048 void KTechlab::requestUpdateCaptions()
01049 {
01050         m_pUpdateCaptionsTimer->start( 0, true );
01051 }
01052 
01053 
01054 void KTechlab::slotUpdateCaptions()
01055 {
01056         //BEGIN Set KTechlab caption
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         //END Set KTechlab caption
01078         
01079         
01080         //BEGIN Set tab captions
01081         emit needUpdateCaptions();
01082         
01083         if ( document && document->activeView() && document->activeView()->viewContainer() )
01084         {
01085                 document->activeView()->viewContainer()->updateCaption();
01086         }
01087         //END Set tab captions
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         // close the first window, the list makes the next one the first again.
01145         // This ensures that queryClose() is called on each window to ask for closing
01146         KMainWindow* w;
01147         if(memberList)
01148         {
01149                 for( w=memberList->first(); w!=0; w=memberList->next() )
01150                 {
01151                         // only close the window if the closeEvent is accepted. If the user presses Cancel on the saveModified() dialog,
01152                         // the window and the application stay open.
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"

Generated on Tue May 8 17:05:30 2007 for KTechLab by  doxygen 1.5.1