00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "kateviewspacecontainer.h"
00023 #include "kateviewspacecontainer.moc"
00024
00025 #include "katetabwidget.h"
00026 #include "katemainwindow.h"
00027 #include "katedocmanager.h"
00028 #include "kateviewmanager.h"
00029 #include "kateviewspace.h"
00030
00031 #include <dcopclient.h>
00032 #include <kaction.h>
00033 #include <kcmdlineargs.h>
00034 #include <kdebug.h>
00035 #include <kdiroperator.h>
00036 #include <kdockwidget.h>
00037 #include <kencodingfiledialog.h>
00038 #include <kiconloader.h>
00039 #include <kglobal.h>
00040 #include <klocale.h>
00041 #include <ktoolbar.h>
00042 #include <kmessagebox.h>
00043 #include <ksimpleconfig.h>
00044 #include <kstdaction.h>
00045 #include <kstandarddirs.h>
00046 #include <kglobalsettings.h>
00047 #include <kstringhandler.h>
00048
00049 #include <ktexteditor/encodinginterface.h>
00050
00051 #include <qlayout.h>
00052 #include <qobjectlist.h>
00053 #include <qstringlist.h>
00054 #include <qvbox.h>
00055 #include <qtimer.h>
00056 #include <qfileinfo.h>
00057
00058
00059
00060 KateViewSpaceContainer::KateViewSpaceContainer (QWidget *parent, KateViewManager *viewManager)
00061 : QVBox (parent)
00062 , m_viewManager(viewManager)
00063 , m_blockViewCreationAndActivation (false)
00064 , m_activeViewRunning (false)
00065 , m_pendingViewCreation(false)
00066 {
00067
00068 m_viewList.setAutoDelete(true);
00069 m_viewSpaceList.setAutoDelete(true);
00070
00071 KateViewSpace* vs = new KateViewSpace( this, this );
00072 connect(this, SIGNAL(statusChanged(Kate::View *, int, int, int, bool, int, const QString&)), vs, SLOT(slotStatusChanged(Kate::View *, int, int, int, bool, int, const QString&)));
00073 vs->setActive( true );
00074 m_viewSpaceList.append(vs);
00075 connect( this, SIGNAL(viewChanged()), this, SLOT(slotViewChanged()) );
00076 connect(KateDocManager::self(), SIGNAL(initialDocumentReplaced()), this, SIGNAL(viewChanged()));
00077
00078 connect(KateDocManager::self(),SIGNAL(documentCreated(Kate::Document *)),this,SLOT(documentCreated(Kate::Document *)));
00079 connect(KateDocManager::self(),SIGNAL(documentDeleted(uint)),this,SLOT(documentDeleted(uint)));
00080 }
00081
00082 KateViewSpaceContainer::~KateViewSpaceContainer ()
00083 {
00084 m_viewList.setAutoDelete(false);
00085 m_viewSpaceList.setAutoDelete(false);
00086 }
00087
00088 void KateViewSpaceContainer::documentCreated (Kate::Document *doc)
00089 {
00090 if (m_blockViewCreationAndActivation) return;
00091
00092 if (!activeView())
00093 activateView (doc->documentNumber());
00094 }
00095
00096 void KateViewSpaceContainer::documentDeleted (uint)
00097 {
00098 if (m_blockViewCreationAndActivation) return;
00099
00100
00101
00102 if (!activeView() && (KateDocManager::self()->documents() > 0))
00103 createView (KateDocManager::self()->document(KateDocManager::self()->documents()-1));
00104 }
00105
00106 bool KateViewSpaceContainer::createView ( Kate::Document *doc )
00107 {
00108 if (m_blockViewCreationAndActivation) return false;
00109
00110
00111 if (!doc)
00112 doc = KateDocManager::self()->createDoc ();
00113
00114
00115 Kate::View *view = (Kate::View *) doc->createView (this, 0L);
00116
00117 m_viewList.append (view);
00118
00119
00120 view->actionCollection()->remove (view->actionCollection()->action( "set_confdlg" ));
00121
00122
00123 view->installPopup ((QPopupMenu*)(mainWindow()->factory()->container("ktexteditor_popup", mainWindow())) );
00124
00125 connect(view->getDoc(),SIGNAL(nameChanged(Kate::Document *)),this,SLOT(statusMsg()));
00126 connect(view,SIGNAL(cursorPositionChanged()),this,SLOT(statusMsg()));
00127 connect(view,SIGNAL(newStatus()),this,SLOT(statusMsg()));
00128 connect(view->getDoc(), SIGNAL(undoChanged()), this, SLOT(statusMsg()));
00129 connect(view,SIGNAL(dropEventPass(QDropEvent *)), mainWindow(),SLOT(slotDropEvent(QDropEvent *)));
00130 connect(view,SIGNAL(gotFocus(Kate::View *)),this,SLOT(activateSpace(Kate::View *)));
00131
00132 activeViewSpace()->addView( view );
00133 activateView( view );
00134 connect( doc, SIGNAL(modifiedOnDisc(Kate::Document *, bool, unsigned char)),
00135 activeViewSpace(), SLOT(modifiedOnDisc(Kate::Document *, bool, unsigned char)) );
00136
00137 return true;
00138 }
00139
00140 bool KateViewSpaceContainer::deleteView (Kate::View *view, bool delViewSpace)
00141 {
00142 if (!view) return true;
00143
00144 KateViewSpace *viewspace = (KateViewSpace *)view->parentWidget()->parentWidget();
00145
00146 viewspace->removeView (view);
00147
00148 mainWindow()->guiFactory ()->removeClient (view);
00149
00150
00151 m_viewList.remove (view);
00152
00153 if (delViewSpace)
00154 if ( viewspace->viewCount() == 0 )
00155 removeViewSpace( viewspace );
00156
00157 return true;
00158 }
00159
00160 KateViewSpace* KateViewSpaceContainer::activeViewSpace ()
00161 {
00162 QPtrListIterator<KateViewSpace> it(m_viewSpaceList);
00163
00164 for (; it.current(); ++it)
00165 {
00166 if ( it.current()->isActiveSpace() )
00167 return it.current();
00168 }
00169
00170 if (m_viewSpaceList.count() > 0)
00171 {
00172 m_viewSpaceList.first()->setActive( true );
00173 return m_viewSpaceList.first();
00174 }
00175
00176 return 0L;
00177 }
00178
00179 Kate::View* KateViewSpaceContainer::activeView ()
00180 {
00181 if (m_activeViewRunning)
00182 return 0L;
00183
00184 m_activeViewRunning = true;
00185
00186 for (QPtrListIterator<Kate::View> it(m_viewList); it.current(); ++it)
00187 {
00188 if ( it.current()->isActive() )
00189 {
00190 m_activeViewRunning = false;
00191 return it.current();
00192 }
00193 }
00194
00195
00196
00197 KateViewSpace* vs;
00198 if ( (vs = activeViewSpace()) )
00199 {
00200 if ( vs->currentView() )
00201 {
00202 activateView (vs->currentView());
00203
00204 m_activeViewRunning = false;
00205 return vs->currentView();
00206 }
00207 }
00208
00209
00210 if (m_viewList.count() > 0)
00211 {
00212 activateView (m_viewList.first());
00213
00214 m_activeViewRunning = false;
00215 return m_viewList.first();
00216 }
00217
00218 m_activeViewRunning = false;
00219
00220
00221 return 0L;
00222 }
00223
00224 void KateViewSpaceContainer::setActiveSpace ( KateViewSpace* vs )
00225 {
00226 if (activeViewSpace())
00227 activeViewSpace()->setActive( false );
00228
00229 vs->setActive( true, viewSpaceCount() > 1 );
00230 }
00231
00232 void KateViewSpaceContainer::setActiveView ( Kate::View* view )
00233 {
00234 if (activeView())
00235 activeView()->setActive( false );
00236
00237 view->setActive( true );
00238 }
00239
00240 void KateViewSpaceContainer::activateSpace (Kate::View* v)
00241 {
00242 if (!v) return;
00243
00244 KateViewSpace* vs = (KateViewSpace*)v->parentWidget()->parentWidget();
00245
00246 if (!vs->isActiveSpace()) {
00247 setActiveSpace (vs);
00248 activateView(v);
00249 }
00250 }
00251
00252 void KateViewSpaceContainer::reactivateActiveView() {
00253 Kate::View *view=activeView();
00254 if (view) {
00255 view->setActive(false);
00256 activateView(view);
00257 } else if (m_pendingViewCreation) {
00258 m_pendingViewCreation=false;
00259 disconnect(m_pendingDocument,SIGNAL(nameChanged(Kate::Document *)),this,SLOT(slotPendingDocumentNameChanged()));
00260 createView(m_pendingDocument);
00261 }
00262 }
00263
00264 void KateViewSpaceContainer::activateView ( Kate::View *view )
00265 {
00266 if (!view) return;
00267
00268 if (!view->isActive())
00269 {
00270 if ( !activeViewSpace()->showView (view) )
00271 {
00272
00273 createView ( view->getDoc() );
00274 return;
00275 }
00276
00277 setActiveView (view);
00278 m_viewList.findRef (view);
00279
00280 mainWindow()->toolBar ()->setUpdatesEnabled (false);
00281
00282 if (m_viewManager->guiMergedView)
00283 mainWindow()->guiFactory()->removeClient (m_viewManager->guiMergedView );
00284
00285 m_viewManager->guiMergedView = view;
00286
00287 if (!m_blockViewCreationAndActivation)
00288 mainWindow()->guiFactory ()->addClient( view );
00289
00290 mainWindow()->toolBar ()->setUpdatesEnabled (true);
00291
00292 statusMsg();
00293
00294 emit viewChanged ();
00295 }
00296
00297 KateDocManager::self()->setActiveDocument(view->getDoc());
00298 }
00299
00300 void KateViewSpaceContainer::activateView( uint documentNumber )
00301 {
00302 if ( activeViewSpace()->showView(documentNumber) ) {
00303 activateView( activeViewSpace()->currentView() );
00304 }
00305 else
00306 {
00307 QPtrListIterator<Kate::View> it(m_viewList);
00308 for ( ;it.current(); ++it)
00309 {
00310 if ( it.current()->getDoc()->documentNumber() == documentNumber )
00311 {
00312 createView( it.current()->getDoc() );
00313 return;
00314 }
00315 }
00316
00317 Kate::Document *d = (Kate::Document *)KateDocManager::self()->documentWithID(documentNumber);
00318 createView (d);
00319 }
00320 }
00321
00322 uint KateViewSpaceContainer::viewCount ()
00323 {
00324 return m_viewList.count();
00325 }
00326
00327 uint KateViewSpaceContainer::viewSpaceCount ()
00328 {
00329 return m_viewSpaceList.count();
00330 }
00331
00332 void KateViewSpaceContainer::slotViewChanged()
00333 {
00334 if ( activeView() && !activeView()->hasFocus())
00335 activeView()->setFocus();
00336 }
00337
00338 void KateViewSpaceContainer::activateNextView()
00339 {
00340 uint i = m_viewSpaceList.find (activeViewSpace())+1;
00341
00342 if (i >= m_viewSpaceList.count())
00343 i=0;
00344
00345 setActiveSpace (m_viewSpaceList.at(i));
00346 activateView(m_viewSpaceList.at(i)->currentView());
00347 }
00348
00349 void KateViewSpaceContainer::activatePrevView()
00350 {
00351 int i = m_viewSpaceList.find (activeViewSpace())-1;
00352
00353 if (i < 0)
00354 i=m_viewSpaceList.count()-1;
00355
00356 setActiveSpace (m_viewSpaceList.at(i));
00357 activateView(m_viewSpaceList.at(i)->currentView());
00358 }
00359
00360 void KateViewSpaceContainer::closeViews(uint documentNumber)
00361 {
00362 QPtrList<Kate::View> closeList;
00363
00364 for (uint z=0 ; z < m_viewList.count(); z++)
00365 {
00366 Kate::View* current = m_viewList.at(z);
00367 if ( current->getDoc()->documentNumber() == documentNumber )
00368 {
00369 closeList.append (current);
00370 }
00371 }
00372
00373 while ( !closeList.isEmpty() )
00374 {
00375 Kate::View *view = closeList.first();
00376 deleteView (view, true);
00377 closeList.removeFirst();
00378 }
00379
00380 if (m_blockViewCreationAndActivation) return;
00381 QTimer::singleShot(0,this,SIGNAL(viewChanged()));
00382
00383 }
00384
00385 void KateViewSpaceContainer::slotPendingDocumentNameChanged() {
00386 QString c;
00387 if (m_pendingDocument->url().isEmpty() || (!showFullPath))
00388 {
00389 c = m_pendingDocument->docName();
00390 }
00391 else
00392 {
00393 c = m_pendingDocument->url().prettyURL();
00394 }
00395 setCaption(KStringHandler::lsqueeze(c,32));
00396 }
00397
00398 void KateViewSpaceContainer::statusMsg ()
00399 {
00400 if (!activeView()) return;
00401
00402 Kate::View* v = activeView();
00403
00404 bool readOnly = !v->getDoc()->isReadWrite();
00405 uint config = v->getDoc()->configFlags();
00406
00407 int ovr = 0;
00408 if (readOnly)
00409 ovr = 0;
00410 else
00411 {
00412 if (config & Kate::Document::cfOvr)
00413 {
00414 ovr=1;
00415 }
00416 else
00417 {
00418 ovr=2;
00419 }
00420 }
00421
00422 int mod = (int)v->getDoc()->isModified();
00423 bool block=v->getDoc()->blockSelectionMode();
00424
00425 QString c;
00426 if (v->getDoc()->url().isEmpty() || (!showFullPath))
00427 {
00428 c = v->getDoc()->docName();
00429 }
00430 else
00431 {
00432 c = v->getDoc()->url().prettyURL();
00433 }
00434
00435 m_viewManager->mainWindow()->tabWidget()->changeTab (this, KStringHandler::lsqueeze(c,32));
00436 emit statusChanged (v, v->cursorLine(), v->cursorColumn(), ovr,block, mod, KStringHandler::lsqueeze(c,64));
00437 emit statChanged ();
00438 }
00439
00440 void KateViewSpaceContainer::splitViewSpace( KateViewSpace* vs,
00441 bool isHoriz,
00442 bool atTop)
00443 {
00444
00445
00446 if (!activeView()) return;
00447 if (!vs) vs = activeViewSpace();
00448
00449 bool isFirstTime = vs->parentWidget() == this;
00450
00451 QValueList<int> psizes;
00452 if ( ! isFirstTime )
00453 if ( QSplitter *ps = static_cast<QSplitter*>(vs->parentWidget()->qt_cast("QSplitter")) )
00454 psizes = ps->sizes();
00455
00456 Qt::Orientation o = isHoriz ? Qt::Vertical : Qt::Horizontal;
00457 KateMDI::Splitter* s = new KateMDI::Splitter(o, vs->parentWidget());
00458 s->setOpaqueResize( KGlobalSettings::opaqueResize() );
00459
00460 if (! isFirstTime) {
00461
00462
00463
00464 if ( !((KateMDI::Splitter*)vs->parentWidget())->isLastChild( vs ) )
00465 ((KateMDI::Splitter*)s->parentWidget())->moveToFirst( s );
00466 }
00467 vs->reparent( s, 0, QPoint(), true );
00468 KateViewSpace* vsNew = new KateViewSpace( this, s );
00469
00470 if (atTop)
00471 s->moveToFirst( vsNew );
00472
00473 if (!isFirstTime)
00474 if (QSplitter *ps = static_cast<QSplitter*>(s->parentWidget()->qt_cast("QSplitter")) )
00475 ps->setSizes( psizes );
00476
00477 s->show();
00478
00479 QValueList<int> sizes;
00480 int space = 50;
00481 sizes << space << space;
00482 s->setSizes( sizes );
00483
00484 connect(this, SIGNAL(statusChanged(Kate::View *, int, int, int, bool, int, const QString &)), vsNew, SLOT(slotStatusChanged(Kate::View *, int, int,int, bool, int, const QString &)));
00485 m_viewSpaceList.append( vsNew );
00486 activeViewSpace()->setActive( false );
00487 vsNew->setActive( true, true );
00488 vsNew->show();
00489
00490 createView (activeView()->getDoc());
00491
00492 if (this == m_viewManager->activeContainer())
00493 m_viewManager->updateViewSpaceActions ();
00494
00495
00496 }
00497
00498 void KateViewSpaceContainer::removeViewSpace (KateViewSpace *viewspace)
00499 {
00500
00501 if (!viewspace) return;
00502
00503
00504 if (m_viewSpaceList.count() < 2) return;
00505
00506 KateMDI::Splitter* p = (KateMDI::Splitter*)viewspace->parentWidget();
00507
00508
00509
00510 bool pIsFirst = false;
00511
00512
00513 KateMDI::Splitter* pp=0L;
00514 QValueList<int> ppsizes;
00515 if (m_viewSpaceList.count() > 2 && p->parentWidget() != this)
00516 {
00517 pp = (KateMDI::Splitter*)p->parentWidget();
00518 ppsizes = pp->sizes();
00519 pIsFirst = !pp->isLastChild( p );
00520 }
00521
00522
00523 KateViewSpace* next;
00524 if (m_viewSpaceList.find(viewspace) == 0)
00525 next = m_viewSpaceList.next();
00526 else
00527 next = m_viewSpaceList.prev();
00528
00529
00530 int vsvc = viewspace->viewCount();
00531 while (vsvc > 0)
00532 {
00533 if (viewspace->currentView())
00534 {
00535 Kate::View* v = viewspace->currentView();
00536
00537 if (v->isLastView())
00538 {
00539 viewspace->removeView(v);
00540 next->addView( v, false );
00541 }
00542 else
00543 {
00544 deleteView( v, false );
00545 }
00546 }
00547 vsvc = viewspace->viewCount();
00548 }
00549
00550 m_viewSpaceList.remove( viewspace );
00551
00552
00553 while (p->children ())
00554 {
00555 QWidget* other = ((QWidget *)(( QPtrList<QObject>*)p->children())->first());
00556
00557 other->reparent( p->parentWidget(), 0, QPoint(), true );
00558
00559 if (pIsFirst)
00560 ((KateMDI::Splitter*)p->parentWidget())->moveToFirst( other );
00561 if ( other->isA("KateViewSpace") ) {
00562 setActiveSpace( (KateViewSpace*)other );
00563 }
00564 else {
00565 QObjectList* l = other->queryList( "KateViewSpace" );
00566 if ( l->first() != 0 ) {
00567 setActiveSpace( (KateViewSpace*)l->first() );
00568 }
00569 delete l;
00570 }
00571 }
00572
00573 delete p;
00574
00575 if (!ppsizes.isEmpty())
00576 pp->setSizes( ppsizes );
00577
00578
00579 Kate::View* v = activeViewSpace()->currentView();
00580 if ( v )
00581 activateView( v );
00582
00583 if (this == m_viewManager->activeContainer())
00584 m_viewManager->updateViewSpaceActions ();
00585
00586 emit viewChanged();
00587 }
00588
00589 void KateViewSpaceContainer::slotCloseCurrentViewSpace()
00590 {
00591 removeViewSpace(activeViewSpace());
00592 }
00593
00594 void KateViewSpaceContainer::setShowFullPath( bool enable )
00595 {
00596 showFullPath = enable;
00597 statusMsg ();
00598
00599 }
00600
00605 void KateViewSpaceContainer::saveViewConfiguration(KConfig *config,const QString& group)
00606 {
00607 bool weHaveSplittersAlive (viewSpaceCount() > 1);
00608
00609 config->setGroup (group);
00610 config->writeEntry ("Splitters", weHaveSplittersAlive);
00611
00612
00613 if (!weHaveSplittersAlive)
00614 {
00615 config->writeEntry("Active Viewspace", 0);
00616 m_viewSpaceList.first()->saveConfig ( config, 0,group );
00617
00618 return;
00619 }
00620
00621
00622 KateMDI::Splitter* s;
00623 QObjectList *l = queryList("KateMDI::Splitter", 0, false, false);
00624 QObjectListIt it( *l );
00625
00626 if ( (s = (KateMDI::Splitter*)it.current()) != 0 )
00627 saveSplitterConfig( s, 0, config , group);
00628
00629 delete l;
00630 }
00631
00632 void KateViewSpaceContainer::restoreViewConfiguration (KConfig *config, const QString& group)
00633 {
00634 config->setGroup(group);
00635
00636
00637
00638 if (!config->readBoolEntry ("Splitters"))
00639 {
00640
00641 m_viewSpaceList.first ()->restoreConfig (this, config, QString(group+"-ViewSpace 0"));
00642 }
00643 else
00644 {
00645
00646 for (uint i=0; i < m_viewList.count(); i++)
00647 mainWindow()->guiFactory ()->removeClient (m_viewList.at(i));
00648
00649 m_viewList.clear ();
00650
00651
00652 m_viewSpaceList.clear();
00653
00654
00655 restoreSplitter( config, QString(group+"-Splitter 0"), this,group );
00656 }
00657
00658
00659 config->setGroup (group);
00660
00661
00662
00663
00664
00665 }
00666
00667
00668 void KateViewSpaceContainer::saveSplitterConfig( KateMDI::Splitter* s, int idx, KConfig* config, const QString& viewConfGrp )
00669 {
00670 QString grp = QString(viewConfGrp+"-Splitter %1").arg(idx);
00671 config->setGroup(grp);
00672
00673
00674 config->writeEntry( "Sizes", s->sizes() );
00675 config->writeEntry( "Orientation", s->orientation() );
00676
00677 QStringList childList;
00678
00679 const QObjectList* l = s->children();
00680 QObjectListIt it( *l );
00681 QObject* obj;
00682 for (; it.current(); ++it) {
00683 obj = it.current();
00684 QString n;
00685
00686 if ( obj->isA("KateViewSpace") ) {
00687 n = QString(viewConfGrp+"-ViewSpace %1").arg( m_viewSpaceList.find((KateViewSpace*)obj) );
00688 ((KateViewSpace*)obj)->saveConfig ( config, m_viewSpaceList.find((KateViewSpace*)obj), viewConfGrp);
00689
00690 if ( ((KateViewSpace*)obj)->isActiveSpace() ) {
00691 config->setGroup(viewConfGrp);
00692 config->writeEntry("Active Viewspace", m_viewSpaceList.find((KateViewSpace*)obj) );
00693 }
00694 }
00695
00696 else if ( obj->isA("KateMDI::Splitter") ) {
00697 idx++;
00698 saveSplitterConfig( (KateMDI::Splitter*)obj, idx, config,viewConfGrp);
00699 n = QString(viewConfGrp+"-Splitter %1").arg( idx );
00700 }
00701
00702 if (!n.isEmpty()) {
00703 if ( childList.count() > 0 && ! s->isLastChild( (QWidget*)obj ) )
00704 childList.prepend( n );
00705 else
00706 childList.append( n );
00707 }
00708 }
00709
00710
00711 config->setGroup(grp);
00712 config->writeEntry("Children", childList);
00713 }
00714
00715 void KateViewSpaceContainer::restoreSplitter( KConfig* config, const QString &group, QWidget* parent, const QString& viewConfGrp)
00716 {
00717 config->setGroup( group );
00718
00719 KateMDI::Splitter* s = new KateMDI::Splitter((Qt::Orientation)config->readNumEntry("Orientation"), parent);
00720
00721 QStringList children = config->readListEntry( "Children" );
00722 for (QStringList::Iterator it=children.begin(); it!=children.end(); ++it)
00723 {
00724
00725 if ( (*it).startsWith(viewConfGrp+"-ViewSpace") )
00726 {
00727 KateViewSpace* vs = new KateViewSpace( this, s );
00728
00729 connect(this, SIGNAL(statusChanged(Kate::View *, int, int, int, bool, int, const QString &)), vs, SLOT(slotStatusChanged(Kate::View *, int, int, int, bool, int, const QString &)));
00730
00731 if (m_viewSpaceList.isEmpty())
00732 vs->setActive (true);
00733
00734 m_viewSpaceList.append( vs );
00735
00736 vs->show();
00737 setActiveSpace( vs );
00738
00739 vs->restoreConfig (this, config, *it);
00740 }
00741 else
00742 {
00743
00744 restoreSplitter( config, QString(*it), s, viewConfGrp );
00745 }
00746 }
00747
00748
00749 config->setGroup( group );
00750 s->setSizes( config->readIntListEntry("Sizes") );
00751 s->show();
00752 }
00753
00754 KateMainWindow *KateViewSpaceContainer::mainWindow() {
00755 return m_viewManager->mainWindow();
00756 }
00757
00758