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/katesort/plugin_sort.cpp

309 lines
9.2 KiB

/***************************************************************************
* Copyright (C) 2007 by Marián Kyral *
* mkyral@email.cz *
* *
* 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., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "plugin_sort.h"
#include "sortdialog.h"
#include <tdeaction.h>
#include <tdelocale.h>
#include <kstandarddirs.h>
#include <map>
#include <tqregexp.h>
class PluginView : public KXMLGUIClient
{
friend class KatePluginSort;
public:
Kate::MainWindow *win;
};
extern "C"
{
KDE_EXPORT void* init_katesortplugin()
{
TDEGlobal::locale()->insertCatalogue("katesort");
return new KatePluginFactory;
}
}
KatePluginFactory::KatePluginFactory()
{
s_instance = new TDEInstance( "kate" );
}
KatePluginFactory::~KatePluginFactory()
{
delete s_instance;
}
TQObject* KatePluginFactory::createObject( TQObject* parent, const char* name, const char*, const TQStringList & )
{
return new KatePluginSort( parent, name );
}
TDEInstance* KatePluginFactory::s_instance = 0L;
KatePluginSort::KatePluginSort( TQObject* parent, const char* name )
: Kate::Plugin ( (Kate::Application*)parent, name )
{
}
KatePluginSort::~KatePluginSort()
{
}
void KatePluginSort::addView(Kate::MainWindow *win)
{
/// @todo doesn't this have to be deleted?
PluginView *view = new PluginView ();
(void) new TDEAction ( i18n("Sort"), 0, this,
TQ_SLOT( slotSort() ), view->actionCollection(),
"edit_insert_sort" );
view->setInstance (new TDEInstance("kate"));
view->setXMLFile("plugins/sort/plugin_sort.rc");
win->guiFactory()->addClient (view);
view->win = win;
m_views.append (view);
}
void KatePluginSort::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);
m_views.remove (view);
win->guiFactory()->removeClient (view);
delete view;
}
}
void KatePluginSort::slotSort()
{
Kate::View *kv = application()->activeMainWindow()->viewManager()->activeView();
if (! kv)
return;
// display dialog part
SortDialog m_sortDialog;
// if only part of one row is selected. update By column part of dialog
if (! kv->getDoc()->selection().isEmpty())
{
if (kv->getDoc()->selStartLine() == kv->getDoc()->selEndLine() &&
kv->getDoc()->lineLength(kv->getDoc()->selStartLine()) != -1 )
{
uint sel_sc = kv->getDoc()->selStartCol() + 1;
uint sel_ec = kv->getDoc()->selEndCol() + 1;
if (! (sel_sc == 0 && (int) sel_ec == kv->getDoc()->lineLength(kv->getDoc()->selStartLine())))
{
m_sortDialog.m_checkBoxByCol->setChecked(true);
m_sortDialog.m_lineEditStartCol->setText(TQString::number(sel_sc,10));
m_sortDialog.m_lineEditEndCol->setText(TQString::number(sel_ec,10));
}
}
kv->getDoc()->clearSelection();
}
if (m_sortDialog.exec() == TQDialog::Rejected)
return;
if (kv->getDoc()->selection().isEmpty())
kv->getDoc()->selectAll();
if (kv->getDoc()->selection().isEmpty())
return; // Nothing to sort !
uint sel_sl = kv->getDoc()->selStartLine();
uint sel_el = kv->getDoc()->selEndLine();
if (kv->getDoc()->selStartCol() > 0 && kv->getDoc()->selStartCol() == kv->getDoc()->lineLength(sel_sl))
sel_sl++ ;
if (kv->getDoc()->selEndCol() == 0 && kv->getDoc()->lineLength(sel_el) >0)
sel_el-- ;
// split string to lines
TQStringMultiMap strMLines; // alphabetical sort multimap
LongMultiMap longMLines; // numerical sort multimap
// Map filling...
TQString skey;
TQString sdata;
int ikey, non_num_ind;
TQRegExp rx("[^0-9]"); // Search regexp for not number character
for (uint i = sel_sl; i <= sel_el; i++)
{
sdata = kv->getDoc()->textLine(i);
skey = sdata;
if (m_sortDialog.m_checkBoxByCol->isChecked())
{
skey = skey.mid(m_sortDialog.m_lineEditStartCol->text().toInt() - 1,
m_sortDialog.m_lineEditEndCol->text().toInt() - m_sortDialog.m_lineEditStartCol->text().toInt());
// tqDebug("skey: %s", skey.ascii());
}
// tqDebug("\tLine: %d",i);
// tqDebug("Key: %s, Line content: %s", skey.ascii(),sdata.ascii());
if (m_sortDialog.m_radioButtonAlphaSort->isChecked())
{
if (m_sortDialog.m_checkBoxCase->isChecked())
{
// Case sensitive sort
strMLines.insert(std::pair<TQString, TQString>(skey ,sdata));
}
else
{
// Case insensitive sort
strMLines.insert(std::pair<TQString, TQString>(skey.lower(), sdata));
}
}
else
{
// Numeric sort
skey = skey.stripWhiteSpace();
if (skey.toLong() == 0)
{ // key is not number
non_num_ind = skey.find(rx,0);
if (non_num_ind != -1)
{ // beginning of key is number
// tqDebug("non_num_ind: %d",non_num_ind);
skey.truncate(non_num_ind);
}
else
{
skey = "0";
}
}
// tqDebug("Key: %s",skey.ascii());
longMLines.insert(std::pair<long, TQString>(skey.toLong(), sdata));
}
}
// Insert result back to document
// Remove selection
kv->getDoc()->removeText(sel_sl,0,sel_el,kv->getDoc()->lineLength(sel_el));
// kv->updateView(false);
TQStringMultiMap::iterator smit, smsit, emsit;
LongMultiMap::iterator lmit, slmit, elmit;
bool fasc;
uint i=sel_sl; // insert start line
bool first=true; // First line flag
TQString prevLine; // Store previous line (for unique purpose)
if (m_sortDialog.m_radioButtonAlphaSort->isChecked())
{
if (m_sortDialog.m_radioButtonAsc->isChecked())
{
// Ascendent
smsit=strMLines.begin();
emsit=strMLines.end();
fasc=true;
} //m_sortDialog.m_radioButtonAsc->isChecked()
else
{
// Descendent
smsit=strMLines.end();
smsit++;
emsit=strMLines.begin();
emsit--;
fasc=false;
} //m_sortDialog.m_radioButtonAsc->isChecked()
for( smit=smsit; smit != emsit; fasc ? ++smit : --smit )
{
sdata = smit->second;
skey = smit->first;
// tqDebug("Key: %s, Line content: %s", skey.ascii(),sdata.ascii());
if (m_sortDialog.m_checkBoxUnique->isChecked())
{
if ( prevLine.compare(sdata) != 0 || first ) //remove duplicities
{
// tqDebug("Inserting line: %d",i);
first = false;
prevLine = sdata;
kv->getDoc()->insertLine(i, sdata);
i++;
}
} // m_sortDialog.m_checkBoxUnique->isChecked()
else
{
prevLine = sdata;
// tqDebug("Inserting line: %d",i);
kv->getDoc()->insertLine(i, sdata);
i++;
} // m_sortDialog.m_checkBoxUnique->isChecked()
} //for
} //m_sortDialog.m_radioButtonAlphaSort->isChecked()
else
{
if (m_sortDialog.m_radioButtonAsc->isChecked())
{
// Ascendent
slmit=longMLines.begin();
elmit=longMLines.end();
fasc=true;
} //m_sortDialog.m_radioButtonAsc->isChecked()
else
{
// Descendent
slmit=longMLines.end();
++slmit;
elmit=longMLines.begin();
--elmit;
fasc=false;
} //m_sortDialog.m_radioButtonAsc->isChecked()
for( lmit=slmit; lmit != elmit; fasc ? ++lmit : --lmit )
{
sdata = lmit->second;
ikey = lmit->first;
// tqDebug("Key: %d, Line content: %s", ikey,sdata.ascii());
if (m_sortDialog.m_checkBoxUnique->isChecked())
{
if ( prevLine.compare(sdata) != 0 || first ) //remove duplicities
{
// tqDebug("Inserting line: %d",i);
first = false;
prevLine = sdata;
kv->getDoc()->insertLine(i, sdata);
i++;
}
} // m_sortDialog.m_checkBoxUnique->isChecked()
else
{
prevLine = sdata;
// tqDebug("Inserting line: %d",i);
kv->getDoc()->insertLine(i, sdata);
i++;
} // m_sortDialog.m_checkBoxUnique->isChecked()
} //for
}
// Delete last blank line
kv->getDoc()->removeLine(i);
}
#include "plugin_sort.moc"