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.
524 lines
15 KiB
524 lines
15 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 <tdeaction.h>
|
|
#include <tdelocale.h>
|
|
#include <kstandarddirs.h>
|
|
#include <tdeglobalsettings.h>
|
|
|
|
#include <kdebug.h>
|
|
#include <tdetoolbar.h>
|
|
#include <tdeconfig.h>
|
|
#include <kiconloader.h>
|
|
#include <tdefiledialog.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"
|
|
{
|
|
KDE_EXPORT void* init_libkatetabbarextensionplugin()
|
|
{
|
|
TDEGlobal::locale()->insertCatalogue("katetabbarextension");
|
|
return new KatePluginFactory;
|
|
}
|
|
}
|
|
|
|
TQObject* KatePluginFactory::createObject(TQObject *parent,
|
|
const char *name, const char*, const TQStringList&)
|
|
{
|
|
return new KatePluginTabBarExtension(parent, name);
|
|
}
|
|
|
|
TDEInstance* KatePluginFactory::s_instance = 0L;
|
|
|
|
// BEGIN KatePluginTabBarExtension
|
|
KatePluginTabBarExtension::KatePluginTabBarExtension(TQObject *parent, const char *name)
|
|
: Kate::Plugin((Kate::Application*)parent, name),
|
|
pConfig(new TDEConfig("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 bSort = pConfig->readBoolEntry("sort", true);
|
|
bool bCloseOnMiddleClick = pConfig->readBoolEntry("closeOnMiddleClick", false);
|
|
|
|
view->tabbar = new KateTabBarExtension(application()->documentManager(),
|
|
win, bHoriz, bSort, bCloseOnMiddleClick, 0, "tabs_hbox");
|
|
|
|
new KWidgetAction(view->tabbar, "tab_bar_widget",
|
|
TDEShortcut::null(), 0, 0, view->actionCollection(), "tabbar_widget");
|
|
|
|
view->setInstance (new TDEInstance("kate"));
|
|
view->setXMLFile("plugins/katetabbarextension/ui.rc");
|
|
win->guiFactory()->addClient (view);
|
|
view->win = win;
|
|
|
|
m_views.append (view);
|
|
|
|
TDEToolBar* toolbar = dynamic_cast<TDEToolBar*>
|
|
(win->guiFactory()->container("tabbarExtensionToolBar", view));
|
|
if (toolbar) {
|
|
connect(toolbar, TQ_SIGNAL(orientationChanged(TQt::Orientation)),
|
|
view->tabbar, TQ_SLOT(slotMoved(TQt::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()==TQt::Horizontal?true:false);
|
|
pConfig->writeEntry("sort", view->tabbar->sortByName());
|
|
pConfig->writeEntry("closeOnMiddleClick", view->tabbar->closeOnMiddleClick());
|
|
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, TQ_SIGNAL(configPageApplyRequest(KateTabBarExtensionConfigPage*)),
|
|
TQ_SLOT(applyConfig(KateTabBarExtensionConfigPage*)) );
|
|
return (Kate::PluginConfigPage*)p;
|
|
}
|
|
|
|
void KatePluginTabBarExtension::initConfigPage(KateTabBarExtensionConfigPage *p)
|
|
{
|
|
p->pSortAlpha->setChecked(m_views.at(0)->tabbar->sortByName());
|
|
p->pCloseOnMiddleClick->setChecked(m_views.at(0)->tabbar->closeOnMiddleClick());
|
|
}
|
|
|
|
void KatePluginTabBarExtension::applyConfig(KateTabBarExtensionConfigPage *p)
|
|
{
|
|
m_views.at(0)->tabbar->setSortByName(p->pSortAlpha->isChecked());
|
|
m_views.at(0)->tabbar->setCloseOnMiddleClick(p->pCloseOnMiddleClick->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(TQWidget::NoFocus);
|
|
|
|
setText(pDoc->docName());
|
|
|
|
connect(this, TQ_SIGNAL(toggled(bool)), TQ_SLOT(setOn(bool)));
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
void KateTabBarButton::mouseReleaseEvent(TQMouseEvent *e)
|
|
{
|
|
// Only handle middle click events when no keyboard modifier is pressed
|
|
if (e->button() == TQt::MidButton && !(e->state() & TQt::KeyButtonMask))
|
|
{
|
|
emit middleButtonPressed(this);
|
|
}
|
|
else
|
|
{
|
|
// Invoke parent handler for unwanted events
|
|
TQPushButton::mouseReleaseEvent(e);
|
|
}
|
|
}
|
|
|
|
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(TDEGlobalSettings::textColor());
|
|
setPaletteForegroundColor( c );
|
|
setIconSet(TQIconSet());
|
|
}
|
|
}
|
|
|
|
void KateTabBarButton::setOn(bool on)
|
|
{
|
|
disconnect( TQ_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, TQ_SIGNAL(toggled(bool)), TQ_SLOT(setOn(bool)));
|
|
}
|
|
// END KateTabBarButton
|
|
|
|
// BEGIN KateTabBarExtension
|
|
KateTabBarExtension::KateTabBarExtension(Kate::DocumentManager *pDocManager,
|
|
Kate::MainWindow *win, bool bHorizOrientation, bool bSort,
|
|
bool bCloseOnMiddleClick, 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 = TQt::Horizontal;
|
|
} else {
|
|
top = new TQBoxLayout(this, TQBoxLayout::TopToBottom);
|
|
m_orientation = TQt::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(), TQ_SIGNAL(viewChanged()), TQ_SLOT(slotViewChanged()));
|
|
connect(pDocManager,
|
|
TQ_SIGNAL(documentCreated(Kate::Document *)),
|
|
TQ_SLOT(slotDocumentCreated(Kate::Document *)));
|
|
connect(pDocManager,
|
|
TQ_SIGNAL(documentDeleted(uint)),
|
|
TQ_SLOT(slotDocumentDeleted(uint)));
|
|
|
|
setSortByName(bSort);
|
|
setCloseOnMiddleClick(bCloseOnMiddleClick);
|
|
}
|
|
|
|
void KateTabBarExtension::slotMoved(TQt::Orientation o)
|
|
{
|
|
// the tabbar moved (top, right, bottom, left or fluently)
|
|
switch (o) {
|
|
case TQt::Vertical:
|
|
top->setDirection(TQBoxLayout::TopToBottom);
|
|
break;
|
|
|
|
case TQt::Horizontal:
|
|
top->setDirection(TQBoxLayout::LeftToRight);
|
|
break;
|
|
}
|
|
|
|
m_orientation = o;
|
|
}
|
|
|
|
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, TQ_SIGNAL(myToggled(KateTabBarButton*)),
|
|
TQ_SLOT(slotActivateView(KateTabBarButton*)));
|
|
connect(tab, TQ_SIGNAL(middleButtonPressed(KateTabBarButton*)),
|
|
TQ_SLOT(slotRequestDocClose(KateTabBarButton*)));
|
|
connect(doc, TQ_SIGNAL(nameChanged(Kate::Document *)),
|
|
TQ_SLOT(slotNameChanged(Kate::Document *)));
|
|
connect(doc, TQ_SIGNAL(modStateChanged(Kate::Document *)),
|
|
TQ_SLOT(slotModChanged(Kate::Document *)));
|
|
connect(doc,
|
|
TQ_SIGNAL(modifiedOnDisc(Kate::Document *, bool, unsigned char)),
|
|
TQ_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;
|
|
}
|
|
}
|
|
}
|
|
|
|
void KateTabBarExtension::slotRequestDocClose(KateTabBarButton *tab)
|
|
{
|
|
if (closeOnMiddleClick() && tab)
|
|
{
|
|
m_docManager->closeDocument(tab->document());
|
|
}
|
|
}
|
|
// 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(1, TQt::Horizontal, i18n("Behavior options"),
|
|
this, "tab_bar_extension_config_page_layout" );
|
|
gb->setInsideSpacing(KDialogBase::spacingHint());
|
|
pSortAlpha = new TQCheckBox(i18n("Sort files alphabetically"), gb);
|
|
pCloseOnMiddleClick = new TQCheckBox(i18n("Close document on mouse middle click"), gb);
|
|
|
|
top->add(gb);
|
|
top->addStretch(1);
|
|
// throw signal changed
|
|
connect(pSortAlpha, TQ_SIGNAL(toggled(bool)), this, TQ_SIGNAL(changed()));
|
|
connect(pCloseOnMiddleClick, TQ_SIGNAL(toggled(bool)), this, TQ_SIGNAL(changed()));
|
|
}
|
|
// 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"
|