summaryrefslogtreecommitdiffstats
path: root/kate/katesort/src/plugin_sort.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kate/katesort/src/plugin_sort.cpp')
-rw-r--r--kate/katesort/src/plugin_sort.cpp308
1 files changed, 308 insertions, 0 deletions
diff --git a/kate/katesort/src/plugin_sort.cpp b/kate/katesort/src/plugin_sort.cpp
new file mode 100644
index 0000000..f74213a
--- /dev/null
+++ b/kate/katesort/src/plugin_sort.cpp
@@ -0,0 +1,308 @@
+/***************************************************************************
+ * 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 <kaction.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+#include <map>
+#include <qregexp.h>
+
+class PluginView : public KXMLGUIClient
+{
+ friend class KatePluginSort;
+
+ public:
+ Kate::MainWindow *win;
+};
+
+extern "C"
+{
+ void* init_libsortplugin()
+ {
+ KGlobal::locale()->insertCatalogue("katesort");
+ return new KatePluginFactory;
+ }
+}
+
+KatePluginFactory::KatePluginFactory()
+{
+ s_instance = new KInstance( "kate" );
+}
+
+KatePluginFactory::~KatePluginFactory()
+{
+ delete s_instance;
+}
+
+QObject* KatePluginFactory::createObject( QObject* parent, const char* name, const char*, const QStringList & )
+{
+ return new KatePluginSort( parent, name );
+}
+
+KInstance* KatePluginFactory::s_instance = 0L;
+
+KatePluginSort::KatePluginSort( QObject* 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 KAction ( i18n("Sort"), 0, this,
+ SLOT( slotSort() ), view->actionCollection(),
+ "edit_insert_sort" );
+
+ view->setInstance (new KInstance("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(QString::number(sel_sc,10));
+ m_sortDialog.m_lineEditEndCol->setText(QString::number(sel_ec,10));
+ }
+ }
+ kv->getDoc()->clearSelection();
+ }
+ if (m_sortDialog.exec() == QDialog::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
+ QStringMultiMap strMLines; // alphabetical sort multimap
+ LongMultiMap longMLines; // numerical sort multimap
+
+
+ // Map filling...
+ QString skey;
+ QString sdata;
+ int ikey, non_num_ind;
+ QRegExp 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());
+// qDebug("skey: %s", skey.ascii());
+ }
+
+// qDebug("\tLine: %d",i);
+// qDebug("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<QString, QString>(skey ,sdata));
+ }
+ else
+ {
+ // Case insensitive sort
+ strMLines.insert(std::pair<QString, QString>(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
+// qDebug("non_num_ind: %d",non_num_ind);
+ skey.truncate(non_num_ind);
+ }
+ else
+ {
+ skey = "0";
+ }
+ }
+// qDebug("Key: %s",skey.ascii());
+ longMLines.insert(std::pair<long, QString>(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);
+
+ QStringMultiMap::iterator smit, smsit, emsit;
+ LongMultiMap::iterator lmit, slmit, elmit;
+ bool fasc;
+ uint i=sel_sl; // insert start line
+ bool first=true; // First line flag
+ QString 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;
+// qDebug("Key: %s, Line content: %s", skey.ascii(),sdata.ascii());
+
+ if (m_sortDialog.m_checkBoxUnique->isChecked())
+ {
+ if ( prevLine.compare(sdata) != 0 || first ) //remove duplicities
+ {
+// qDebug("Inserting line: %d",i);
+ first = false;
+ prevLine = sdata;
+ kv->getDoc()->insertLine(i, sdata);
+ i++;
+ }
+ } // m_sortDialog.m_checkBoxUnique->isChecked()
+ else
+ {
+ prevLine = sdata;
+// qDebug("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;
+
+// qDebug("Key: %d, Line content: %s", ikey,sdata.ascii());
+ if (m_sortDialog.m_checkBoxUnique->isChecked())
+ {
+ if ( prevLine.compare(sdata) != 0 || first ) //remove duplicities
+ {
+// qDebug("Inserting line: %d",i);
+ first = false;
+ prevLine = sdata;
+ kv->getDoc()->insertLine(i, sdata);
+ i++;
+ }
+ } // m_sortDialog.m_checkBoxUnique->isChecked()
+ else
+ {
+ prevLine = sdata;
+// qDebug("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"
+