kateviewspace.cpp
00001 /* This file is part of the KDE project 00002 Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org> 00003 Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org> 00004 Copyright (C) 2001, 2005 Anders Lund <anders.lund@lund.tdcadsl.dk> 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License version 2 as published by the Free Software Foundation. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to 00017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00018 Boston, MA 02110-1301, USA. 00019 */ 00020 00021 #include "kateviewspace.h" 00022 #include "kateviewspace.moc" 00023 00024 #include "katemainwindow.h" 00025 #include "kateviewspacecontainer.h" 00026 #include "katedocmanager.h" 00027 #include "kateapp.h" 00028 #include "katesession.h" 00029 00030 #include <kiconloader.h> 00031 #include <tdelocale.h> 00032 #include <ksqueezedtextlabel.h> 00033 #include <tdeconfig.h> 00034 #include <kdebug.h> 00035 00036 #include <tqwidgetstack.h> 00037 #include <tqpainter.h> 00038 #include <tqlabel.h> 00039 #include <tqcursor.h> 00040 #include <tqpopupmenu.h> 00041 #include <tqpixmap.h> 00042 00043 //BEGIN KVSSBSep 00044 /* 00045 "KateViewSpaceStatusBarSeparator" 00046 A 2 px line to separate the statusbar from the view. 00047 It is here to compensate for the lack of a frame in the view, 00048 I think Kate looks very nice this way, as TQScrollView with frame 00049 looks slightly clumsy... 00050 Slight 3D effect. I looked for suitable TQStyle props or methods, 00051 but found none, though maybe it should use TQStyle::PM_DefaultFrameWidth 00052 for height (TRY!). 00053 It does look a bit funny with flat styles (Light, .Net) as is, 00054 but there are on methods to paint panel lines separately. And, 00055 those styles tends to look funny on their own, as a light line 00056 in a 3D frame next to a light contents widget is not functional. 00057 Also, TQStatusBar is up to now completely ignorant to style. 00058 -anders 00059 */ 00060 class KVSSBSep : public TQWidget { 00061 public: 00062 KVSSBSep( KateViewSpace *parent=0) : TQWidget(parent) 00063 { 00064 setFixedHeight( 2 ); 00065 } 00066 protected: 00067 void paintEvent( TQPaintEvent *e ) 00068 { 00069 TQPainter p( this ); 00070 p.setPen( colorGroup().shadow() ); 00071 p.drawLine( e->rect().left(), 0, e->rect().right(), 0 ); 00072 p.setPen( ((KateViewSpace*)parentWidget())->isActiveSpace() ? colorGroup().light() : colorGroup().midlight() ); 00073 p.drawLine( e->rect().left(), 1, e->rect().right(), 1 ); 00074 } 00075 }; 00076 //END KVSSBSep 00077 00078 //BEGIN KateViewSpace 00079 KateViewSpace::KateViewSpace( KateViewSpaceContainer *viewManager, 00080 TQWidget* parent, const char* name ) 00081 : TQVBox(parent, name), 00082 m_viewManager( viewManager ) 00083 { 00084 mViewList.setAutoDelete(false); 00085 00086 stack = new TQWidgetStack( this ); 00087 setStretchFactor(stack, 1); 00088 stack->setFocus(); 00089 //sep = new KVSSBSep( this ); 00090 mStatusBar = new KateVSStatusBar(this); 00091 mIsActiveSpace = false; 00092 mViewCount = 0; 00093 00094 setMinimumWidth (mStatusBar->minimumWidth()); 00095 m_group = TQString::null; 00096 } 00097 00098 KateViewSpace::~KateViewSpace() 00099 { 00100 } 00101 00102 void KateViewSpace::polish() 00103 { 00104 mStatusBar->show(); 00105 } 00106 00107 void KateViewSpace::addView(Kate::View* v, bool show) 00108 { 00109 // restore the config of this view if possible 00110 if ( !m_group.isEmpty() ) 00111 { 00112 TQString fn = v->getDoc()->url().prettyURL(); 00113 if ( ! fn.isEmpty() ) 00114 { 00115 TQString vgroup = TQString("%1 %2").arg(m_group).arg(fn); 00116 00117 KateSession::Ptr as = KateSessionManager::self()->activeSession (); 00118 if ( as->configRead() && as->configRead()->hasGroup( vgroup ) ) 00119 { 00120 as->configRead()->setGroup( vgroup ); 00121 v->readSessionConfig ( as->configRead() ); 00122 } 00123 } 00124 } 00125 00126 uint id = mViewList.count(); 00127 stack->addWidget(v, id); 00128 if (show) { 00129 mViewList.append(v); 00130 showView( v ); 00131 } 00132 else { 00133 Kate::View* c = mViewList.current(); 00134 mViewList.prepend( v ); 00135 showView( c ); 00136 } 00137 } 00138 00139 void KateViewSpace::removeView(Kate::View* v) 00140 { 00141 disconnect( v->getDoc(), TQT_SIGNAL(modifiedChanged()), 00142 mStatusBar, TQT_SLOT(modifiedChanged()) ); 00143 00144 bool active = ( v == currentView() ); 00145 00146 mViewList.remove (v); 00147 stack->removeWidget (v); 00148 00149 if ( ! active ) 00150 return; 00151 00152 if (currentView() != 0L) 00153 showView(mViewList.current()); 00154 else if (mViewList.count() > 0) 00155 showView(mViewList.last()); 00156 } 00157 00158 bool KateViewSpace::showView(Kate::View* v) 00159 { 00160 return showView( v->getDoc()->documentNumber() ); 00161 } 00162 00163 bool KateViewSpace::showView(uint documentNumber) 00164 { 00165 TQPtrListIterator<Kate::View> it (mViewList); 00166 it.toLast(); 00167 for( ; it.current(); --it ) { 00168 if (((Kate::Document*)it.current()->getDoc())->documentNumber() == documentNumber) { 00169 if ( currentView() ) 00170 disconnect( currentView()->getDoc(), TQT_SIGNAL(modifiedChanged()), 00171 mStatusBar, TQT_SLOT(modifiedChanged()) ); 00172 00173 Kate::View* kv = it.current(); 00174 connect( kv->getDoc(), TQT_SIGNAL(modifiedChanged()), 00175 mStatusBar, TQT_SLOT(modifiedChanged()) ); 00176 00177 mViewList.removeRef( kv ); 00178 mViewList.append( kv ); 00179 stack->raiseWidget( kv ); 00180 kv->show(); 00181 mStatusBar->modifiedChanged(); 00182 return true; 00183 } 00184 } 00185 return false; 00186 } 00187 00188 00189 Kate::View* KateViewSpace::currentView() 00190 { 00191 if (mViewList.count() > 0) 00192 return (Kate::View*)stack->visibleWidget(); 00193 00194 return 0L; 00195 } 00196 00197 bool KateViewSpace::isActiveSpace() 00198 { 00199 return mIsActiveSpace; 00200 } 00201 00202 void KateViewSpace::setActive( bool active, bool ) 00203 { 00204 mIsActiveSpace = active; 00205 00206 // change the statusbar palette and make sure it gets updated 00207 TQPalette pal( palette() ); 00208 if ( ! active ) 00209 { 00210 pal.setColor( TQColorGroup::Background, pal.active().mid() ); 00211 pal.setColor( TQColorGroup::Light, pal.active().midlight() ); 00212 } 00213 00214 mStatusBar->setPalette( pal ); 00215 mStatusBar->update(); 00216 //sep->update(); 00217 } 00218 00219 bool KateViewSpace::event( TQEvent *e ) 00220 { 00221 if ( e->type() == TQEvent::PaletteChange ) 00222 { 00223 setActive( mIsActiveSpace ); 00224 return true; 00225 } 00226 return TQVBox::event( e ); 00227 } 00228 00229 void KateViewSpace::slotStatusChanged (Kate::View *view, int r, int c, int ovr, bool block, int mod, const TQString &msg) 00230 { 00231 if ((TQWidgetStack *)view->parentWidget() != stack) 00232 return; 00233 mStatusBar->setStatus( r, c, ovr, block, mod, msg ); 00234 } 00235 00236 void KateViewSpace::saveConfig ( TDEConfig* config, int myIndex ,const TQString& viewConfGrp) 00237 { 00238 // kdDebug()<<"KateViewSpace::saveConfig("<<myIndex<<", "<<viewConfGrp<<") - currentView: "<<currentView()<<")"<<endl; 00239 TQString group = TQString(viewConfGrp+"-ViewSpace %1").arg( myIndex ); 00240 00241 config->setGroup (group); 00242 config->writeEntry ("Count", mViewList.count()); 00243 00244 if (currentView()) 00245 config->writeEntry( "Active View", currentView()->getDoc()->url().prettyURL() ); 00246 00247 // Save file list, including cursor position in this instance. 00248 TQPtrListIterator<Kate::View> it(mViewList); 00249 00250 int idx = 0; 00251 for (; it.current(); ++it) 00252 { 00253 if ( !it.current()->getDoc()->url().isEmpty() ) 00254 { 00255 long docListPos = it.current()->getDoc()->documentListPosition(); 00256 config->setGroup( group ); 00257 config->writeEntry( TQString("View %1").arg( (docListPos<0)?idx:docListPos ), it.current()->getDoc()->url().prettyURL() ); 00258 00259 // view config, group: "ViewSpace <n> url" 00260 TQString vgroup = TQString("%1 %2").arg(group).arg(it.current()->getDoc()->url().prettyURL()); 00261 config->setGroup( vgroup ); 00262 it.current()->writeSessionConfig( config ); 00263 } 00264 00265 idx++; 00266 } 00267 } 00268 00269 void KateViewSpace::modifiedOnDisc(Kate::Document *, bool, unsigned char) 00270 { 00271 if ( currentView() ) 00272 mStatusBar->updateMod( currentView()->getDoc()->isModified() ); 00273 } 00274 00275 void KateViewSpace::restoreConfig ( KateViewSpaceContainer *viewMan, TDEConfig* config, const TQString &group ) 00276 { 00277 config->setGroup (group); 00278 TQString fn = config->readEntry( "Active View" ); 00279 00280 if ( !fn.isEmpty() ) 00281 { 00282 Kate::Document *doc = KateDocManager::self()->findDocumentByUrl (KURL(fn)); 00283 00284 if (doc) 00285 { 00286 // view config, group: "ViewSpace <n> url" 00287 TQString vgroup = TQString("%1 %2").arg(group).arg(fn); 00288 config->setGroup( vgroup ); 00289 00290 viewMan->createView (doc); 00291 00292 Kate::View *v = viewMan->activeView (); 00293 00294 if (v) 00295 v->readSessionConfig( config ); 00296 } 00297 } 00298 00299 if (mViewList.isEmpty()) 00300 viewMan->createView (KateDocManager::self()->document(0)); 00301 00302 m_group = group; // used for restroing view configs later 00303 } 00304 //END KateViewSpace 00305 00306 //BEGIN KateVSStatusBar 00307 KateVSStatusBar::KateVSStatusBar ( KateViewSpace *parent, const char *name ) 00308 : KStatusBar( parent, name ), 00309 m_viewSpace( parent ) 00310 { 00311 m_lineColLabel = new TQLabel( this ); 00312 addWidget( m_lineColLabel, 0, false ); 00313 m_lineColLabel->setAlignment( Qt::AlignCenter ); 00314 m_lineColLabel->installEventFilter( this ); 00315 00316 m_modifiedLabel = new TQLabel( TQString(" "), this ); 00317 addWidget( m_modifiedLabel, 0, false ); 00318 m_modifiedLabel->setAlignment( Qt::AlignCenter ); 00319 m_modifiedLabel->installEventFilter( this ); 00320 00321 m_insertModeLabel = new TQLabel( i18n(" INS "), this ); 00322 addWidget( m_insertModeLabel, 0, false ); 00323 m_insertModeLabel->setAlignment( Qt::AlignCenter ); 00324 m_insertModeLabel->installEventFilter( this ); 00325 00326 m_selectModeLabel = new TQLabel( i18n(" NORM "), this ); 00327 addWidget( m_selectModeLabel, 0, false ); 00328 m_selectModeLabel->setAlignment( Qt::AlignCenter ); 00329 m_selectModeLabel->installEventFilter( this ); 00330 00331 m_fileNameLabel=new KSqueezedTextLabel( this ); 00332 addWidget( m_fileNameLabel, 1, true ); 00333 m_fileNameLabel->setMinimumSize( 0, 0 ); 00334 m_fileNameLabel->setSizePolicy(TQSizePolicy( TQSizePolicy::Ignored, TQSizePolicy::Fixed )); 00335 m_fileNameLabel->setAlignment( /*Qt::AlignRight*/Qt::AlignLeft ); 00336 m_fileNameLabel->installEventFilter( this ); 00337 00338 installEventFilter( this ); 00339 m_modPm = SmallIcon("modified"); 00340 m_modDiscPm = SmallIcon("modonhd"); 00341 m_modmodPm = SmallIcon("modmod"); 00342 m_noPm = SmallIcon("null"); 00343 } 00344 00345 KateVSStatusBar::~KateVSStatusBar () 00346 { 00347 } 00348 00349 void KateVSStatusBar::setStatus( int r, int c, int ovr, bool block, int, const TQString &msg ) 00350 { 00351 m_lineColLabel->setText( 00352 i18n(" Line: %1 Col: %2 ").arg(TDEGlobal::locale()->formatNumber(r+1, 0)) 00353 .arg(TDEGlobal::locale()->formatNumber(c+1, 0)) ); 00354 00355 if (ovr == 0) 00356 m_insertModeLabel->setText( i18n(" R/O ") ); 00357 else if (ovr == 1) 00358 m_insertModeLabel->setText( i18n(" OVR ") ); 00359 else if (ovr == 2) 00360 m_insertModeLabel->setText( i18n(" INS ") ); 00361 00362 // updateMod( mod ); 00363 00364 m_selectModeLabel->setText( block ? i18n(" BLK ") : i18n(" NORM ") ); 00365 00366 m_fileNameLabel->setText( msg ); 00367 } 00368 00369 void KateVSStatusBar::updateMod( bool mod ) 00370 { 00371 Kate::View *v = m_viewSpace->currentView(); 00372 if ( v ) 00373 { 00374 const KateDocumentInfo *info 00375 = KateDocManager::self()->documentInfo ( v->getDoc() ); 00376 00377 bool modOnHD = info && info->modifiedOnDisc; 00378 00379 m_modifiedLabel->setPixmap( 00380 mod ? 00381 info && modOnHD ? 00382 m_modmodPm : 00383 m_modPm : 00384 info && modOnHD ? 00385 m_modDiscPm : 00386 m_noPm 00387 ); 00388 } 00389 } 00390 00391 void KateVSStatusBar::modifiedChanged() 00392 { 00393 Kate::View *v = m_viewSpace->currentView(); 00394 if ( v ) 00395 updateMod( v->getDoc()->isModified() ); 00396 } 00397 00398 void KateVSStatusBar::showMenu() 00399 { 00400 TDEMainWindow* mainWindow = static_cast<TDEMainWindow*>( topLevelWidget() ); 00401 TQPopupMenu* menu = static_cast<TQPopupMenu*>( mainWindow->factory()->container("viewspace_popup", mainWindow ) ); 00402 00403 if (menu) 00404 menu->exec(TQCursor::pos()); 00405 } 00406 00407 bool KateVSStatusBar::eventFilter(TQObject*,TQEvent *e) 00408 { 00409 if (e->type()==TQEvent::MouseButtonPress) 00410 { 00411 if ( m_viewSpace->currentView() ) 00412 m_viewSpace->currentView()->setFocus(); 00413 00414 if ( ((TQMouseEvent*)e)->button()==Qt::RightButton) 00415 showMenu(); 00416 00417 return true; 00418 } 00419 00420 return false; 00421 } 00422 //END KateVSStatusBar 00423 // kate: space-indent on; indent-width 2; replace-tabs on;