You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdeaddons/kate/tabbarextension/plugin_katetabbarextension.cpp

531 lines
14 KiB

/***************************************************************************
plugin_katetabbarextension.cpp
-------------------
begin : 2004-04-20
copyright : (C) 2004 by Dominik Haumann
email : dhdev@gmx.de
***************************************************************************/
/***************************************************************************
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
***************************************************************************/
// BEGIN INCLUDES
#include "plugin_katetabbarextension.h"
#include <kaction.h>
#include <klocale.h>
#include <kstandarddirs.h>
#include <kglobalsettings.h>
#include <kdebug.h>
#include <ktoolbar.h>
#include <kconfig.h>
#include <kiconloader.h>
#include <kfiledialog.h>
#include <tqpushbutton.h>
#include <tqlayout.h>
#include <tqtooltip.h>
#include <tqgroupbox.h>
#include <tqcheckbox.h>
// END
class PluginView : public KXMLGUIClient
{
friend class KatePluginTabBarExtension;
public:
Kate::MainWindow *win;
KateTabBarExtension* tabbar;
};
extern "C"
{
void* init_libkatetabbarextensionplugin()
{
KGlobal::locale()->insertCatalogue("katetabbarextension");
return new KatePluginFactory;
}
}
KatePluginFactory::KatePluginFactory()
{
s_instance = new KInstance( "kate" );
}
KatePluginFactory::~KatePluginFactory()
{
delete s_instance;
}
TQObject* KatePluginFactory::createObject(
TQObject* parent, const char* name, const char*, const TQStringList & )
{
return new KatePluginTabBarExtension( parent, name );
}
KInstance* KatePluginFactory::s_instance = 0L;
// BEGIN KatePluginTabBarExtension
KatePluginTabBarExtension::KatePluginTabBarExtension(
TQObject* parent, const char* name )
: Kate::Plugin ( (Kate::Application*)parent, name ),
pConfig(new KConfig("katetabbarextensionpluginrc"))
{
pConfig->setGroup("global");
}
KatePluginTabBarExtension::~KatePluginTabBarExtension()
{
while (m_views.count() > 0)
{
removeView(m_views.at(0)->win);
}
delete pConfig;
}
void KatePluginTabBarExtension::addView(Kate::MainWindow *win)
{
PluginView *view = new PluginView ();
bool bHoriz = pConfig->readBoolEntry("horizontal orientation", true);
bool sort = pConfig->readBoolEntry("sort", true);
view->tabbar = new KateTabBarExtension( application()->documentManager(),
win, bHoriz, sort, 0, "tabs_hbox");
new KWidgetAction(view->tabbar, "tab_bar_widget",
KShortcut::null(), 0, 0, view->actionCollection(), "tabbar_widget");
view->setInstance (new KInstance("kate"));
view->setXMLFile("plugins/katetabbarextension/ui.rc");
win->guiFactory()->addClient (view);
view->win = win;
m_views.append (view);
KToolBar* toolbar = dynamic_cast<KToolBar*>
(win->guiFactory()->container("tabbarExtensionToolBar", view));
if (toolbar) {
connect(toolbar, TQT_SIGNAL( orientationChanged(Qt::Orientation) ),
view->tabbar, TQT_SLOT( slotMoved(Qt::Orientation) ));
}
}
void KatePluginTabBarExtension::removeView(Kate::MainWindow *win)
{
for (uint z=0; z < m_views.count(); z++) {
if (m_views.at(z)->win == win)
{
PluginView *view = m_views.at(z);
// the last tabbar, save options
if (m_views.count() == 1)
{
pConfig->writeEntry("horizontal orientation",
view->tabbar->orientation()==Qt::Horizontal?true:false);
pConfig->writeEntry("sort", view->tabbar->sortByName());
pConfig->sync();
}
m_views.remove (view);
win->guiFactory()->removeClient (view);
delete view->tabbar;
delete view;
}
}
}
Kate::PluginConfigPage* KatePluginTabBarExtension::configPage(
uint, TQWidget *w, const char* /*name*/)
{
KateTabBarExtensionConfigPage* p = new KateTabBarExtensionConfigPage(this, w);
initConfigPage( p );
connect( p, TQT_SIGNAL(configPageApplyRequest(KateTabBarExtensionConfigPage*)),
TQT_SLOT(applyConfig(KateTabBarExtensionConfigPage*)) );
return (Kate::PluginConfigPage*)p;
}
void KatePluginTabBarExtension::initConfigPage( KateTabBarExtensionConfigPage* p )
{
p->pSortAlpha->setChecked(m_views.at(0)->tabbar->sortByName());
}
void KatePluginTabBarExtension::applyConfig( KateTabBarExtensionConfigPage* p )
{
m_views.at(0)->tabbar->setSortByName(p->pSortAlpha->isChecked());
// sync m_config in destructor
}
// END KatePluginTabBarExtension
// BEGIN KateTabBarButton
KateTabBarButton::KateTabBarButton(Kate::ViewManager* pViewManager,
Kate::Document *pDoc, TQWidget * parent, const char * name)
: TQPushButton(parent, name),
modified(false),
myDocID(pDoc->documentNumber()),
doc(pDoc),
viewManager(pViewManager)
{
setFlat(true);
setToggleButton(true);
setFocusPolicy(TQ_NoFocus);
setText(pDoc->docName());
connect(this, TQT_SIGNAL(toggled(bool)), TQT_SLOT(setOn(bool)));
}
KateTabBarButton::~KateTabBarButton() {}
uint KateTabBarButton::documentNumber()
{
return myDocID;
}
void KateTabBarButton::setDirty(bool d)
{
if (d) {
setIconSet(SmallIconSet("cancel"));
} else {
if (modified) setIconSet(SmallIconSet("modified"));
else setIconSet(TQIconSet());
}
}
void KateTabBarButton::setText( const TQString& newText)
{
TQToolTip::remove(this);
if (newText.length() > 20) {
// squeeze to length 17+3=20
TQPushButton::setText(newText.left(9) + "..." + newText.right(8));
TQToolTip::add(this, newText);
} else {
TQPushButton::setText(newText);
}
}
TQString KateTabBarButton::fullName() const
{
if (doc) {
return doc->docName();
} else {
return TQString("");
}
}
void KateTabBarButton::triggerModified()
{
modified = !modified;
if (modified) {
TQColor c(255, 0, 0);
setPaletteForegroundColor( c );
setIconSet(SmallIconSet("modified"));
} else {
TQColor c(KGlobalSettings::textColor());
setPaletteForegroundColor( c );
setIconSet(TQIconSet());
}
}
void KateTabBarButton::setOn(bool on)
{
disconnect( TQT_SIGNAL(toggled(bool)));
// kdDebug() << "setOn: " << (int)on << endl;
if ((!on) && viewManager->activeView()->document()->documentNumber()
== documentNumber()) {
// kdDebug() << "setOn aborted " << endl;
TQPushButton::setOn(true);
} else {
TQPushButton::setOn(on);
if (on) emit myToggled(this);
}
connect(this, TQT_SIGNAL(toggled(bool)), TQT_SLOT(setOn(bool)));
}
// END KateTabBarButton
// BEGIN KateTabBarExtension
KateTabBarExtension::KateTabBarExtension( Kate::DocumentManager *pDocManager,
Kate::MainWindow *win, bool bHorizOrientation, bool bSort,
TQWidget* parent, const char* name, WFlags f )
: TQWidget(parent, name, f),
pCurrentTab(0), m_win(win), m_docManager(pDocManager), m_sort(false)
{
if (bHorizOrientation) {
top = new TQBoxLayout(this, TQBoxLayout::LeftToRight);
m_orientation = Qt::Horizontal;
} else {
top = new TQBoxLayout(this, TQBoxLayout::TopToBottom);
m_orientation = Qt::Vertical;
}
// add all already existing documents to the tabbar
for (uint i = 0; i < pDocManager->documents(); i++)
{
slotDocumentCreated (pDocManager->document(i));
}
connect(m_win->viewManager(), TQT_SIGNAL(viewChanged()), TQT_SLOT(slotViewChanged()));
connect(pDocManager,
TQT_SIGNAL(documentCreated(Kate::Document *)),
TQT_SLOT(slotDocumentCreated(Kate::Document *)));
connect(pDocManager,
TQT_SIGNAL(documentDeleted(uint)),
TQT_SLOT(slotDocumentDeleted(uint)));
setSortByName(bSort);
}
KateTabBarExtension::~KateTabBarExtension() {}
void KateTabBarExtension::slotMoved(Qt::Orientation o)
{
// the tabbar moved (top, right, bottom, left or fluently)
switch (o) {
case Qt::Vertical:
top->setDirection(TQBoxLayout::TopToBottom);
break;
case Qt::Horizontal:
top->setDirection(TQBoxLayout::LeftToRight);
break;
}
m_orientation = o;
}
Qt::Orientation KateTabBarExtension::orientation() const
{
return m_orientation;
}
bool KateTabBarExtension::sortByName() const
{
return m_sort;
}
void KateTabBarExtension::setSortByName(bool sbn)
{
if (m_sort != sbn) {
m_sort = sbn;
if (m_sort)
updateSort();
}
}
void KateTabBarExtension::updateSort()
{
// kdDebug() << "updateSort called" << endl;
if (sortByName()) {
// remove all tabs from the tabbar
KateTabBarButton* tab;
for (tab = m_tabs.first(); tab; tab = m_tabs.next() ) {
top->remove(tab);
}
// now sort
m_tabs.sort();
// and finally add tabs again. FIXME: Is there a better way? :(
for (tab = m_tabs.first(); tab; tab = m_tabs.next() ) {
top->addWidget(tab);
}
}
}
void KateTabBarExtension::slotDocumentCreated (Kate::Document *doc)
{
// kdDebug() << "slotDocumentCreated" << endl;
if (!doc) return;
KateTabBarButton* tab = new KateTabBarButton(m_win->viewManager(), doc, this);
connect(tab, TQT_SIGNAL(myToggled(KateTabBarButton*)),
TQT_SLOT(slotActivateView(KateTabBarButton*)));
connect(doc, TQT_SIGNAL(nameChanged(Kate::Document *)),
TQT_SLOT(slotNameChanged(Kate::Document *)));
connect(doc, TQT_SIGNAL(modStateChanged(Kate::Document *)),
TQT_SLOT(slotModChanged(Kate::Document *)));
connect(doc,
TQT_SIGNAL(modifiedOnDisc(Kate::Document *, bool, unsigned char)),
TQT_SLOT(slotModifiedOnDisc(Kate::Document *, bool, unsigned char)));
if(doc->isModified()) tab->triggerModified();
tab->show();
top->addWidget(tab);
m_tabs.append(tab);
updateSort();
}
void KateTabBarExtension::slotDocumentDeleted (uint documentNumber)
{
// kdDebug() << "slotDocumentDeleted " << endl;
KateTabBarButton* tab;
for (tab = m_tabs.first(); tab; tab = m_tabs.next() ) {
if (tab->documentNumber() == documentNumber) {
tab->disconnect();
top->remove(tab);
m_tabs.removeRef(tab);
delete tab;
tab = 0;
break;
}
}
}
void KateTabBarExtension::slotActivateView(KateTabBarButton* newTab)
{
// kdDebug() << "slotActiavateView" << endl;
pCurrentTab = newTab;
if (pCurrentTab) {
KateTabBarButton* tab;
for (tab = m_tabs.first(); tab; tab = m_tabs.next() ) {
if (tab->isOn() && tab != pCurrentTab)
tab->setOn(false);
}
uint id = pCurrentTab->documentNumber();
m_win->viewManager()->activateView( id );
}
}
void KateTabBarExtension::slotModChanged (Kate::Document *doc)
{
// kdDebug() << "slotModChanged" << endl;
if (!doc) return;
KateTabBarButton* tab;
for (tab = m_tabs.first(); tab; tab = m_tabs.next() ) {
if (tab->documentNumber() == doc->documentNumber()) {
// found
tab->triggerModified();
break;
}
}
}
void KateTabBarExtension::slotModifiedOnDisc (
Kate::Document *doc, bool b, unsigned char /*reason*/)
{
// kdDebug() << "slotModifiedOnDisc: " << (int)b << endl;
// find corresponding tab
KateTabBarButton* tab;
for (tab = m_tabs.first(); tab; tab = m_tabs.next() ) {
if (tab->documentNumber() == doc->documentNumber()) {
tab->setDirty(b);
}
}
}
void KateTabBarExtension::slotNameChanged (Kate::Document *doc)
{
if (!doc) return;
// kdDebug() << "slotNameChanged " << doc->docName() << endl;
KateTabBarButton* tab;
for (tab = m_tabs.first(); tab; tab = m_tabs.next() ) {
if (tab->documentNumber() == doc->documentNumber()) {
tab->setText(doc->docName());
break;
}
}
updateSort();
}
void KateTabBarExtension::slotViewChanged ()
{
// kdDebug() << "slotVieChanged()" << endl;
Kate::View *view = m_win->viewManager()->activeView();
if (!view) return;
KateTabBarButton* tab;
for (tab = m_tabs.first(); tab; tab = m_tabs.next() ) {
if (tab->documentNumber()
== ((Kate::Document *)view->getDoc())->documentNumber()) {
pCurrentTab = tab;
for (tab = m_tabs.first(); tab; tab = m_tabs.next() ) {
if (tab->isOn()) tab->setOn(false);
}
if (!pCurrentTab->isOn()) pCurrentTab->setOn(true);
break;
}
}
}
// END KateTabBarExtension
// BEGIN KateTabBarExtensionConfigPage
KateTabBarExtensionConfigPage::KateTabBarExtensionConfigPage(
TQObject* /*parent*/ /*= 0L*/, TQWidget *parentWidget /*= 0L*/)
: Kate::PluginConfigPage( parentWidget )
{
TQVBoxLayout* top = new TQVBoxLayout(this, 0,
KDialogBase::spacingHint());
TQGroupBox* gb = new TQGroupBox( i18n("Sorting Behavior"),
this, "tab_bar_extension_config_page_layout" );
gb->setColumnLayout(1, Qt::Vertical);
gb->setInsideSpacing(KDialogBase::spacingHint());
pSortAlpha = new TQCheckBox(i18n("Sort files alphabetically"), gb);
top->add(gb);
top->addStretch(1);
// throw signal changed
connect(pSortAlpha, TQT_SIGNAL(toggled(bool)), this, TQT_SIGNAL(changed()));
}
KateTabBarExtensionConfigPage::~KateTabBarExtensionConfigPage() {}
void KateTabBarExtensionConfigPage::apply()
{
emit configPageApplyRequest( this );
}
// END KateTabBarExtensionConfigPage
// BEGIN MyPtrList implementaion
int MyPtrList::compareItems ( TQPtrCollection::Item item1_,
TQPtrCollection::Item item2_ )
{
KateTabBarButton* item1 = reinterpret_cast<KateTabBarButton*>(item1_);
KateTabBarButton* item2 = reinterpret_cast<KateTabBarButton*>(item2_);
if (item1->fullName().lower() < item2->fullName().lower()) {
// kdDebug() << item1->fullName().lower() << " < "
// << item2->fullName().lower() << endl;
return -1;
} else {
if (item1->fullName().lower() > item2->fullName().lower()) {
// kdDebug() << item1->fullName().lower() << " > "
// << item2->fullName().lower() << endl;
return 1;
} else {
// kdDebug() << item1->fullName().lower() << " == "
// << item2->fullName().lower() << endl;
return 0;
}
}
}
// END MyPtrList implementaion
#include "plugin_katetabbarextension.moc"