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