/*************************************************************************** * 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 #include #include #include #include class PluginView : public KXMLGUIClient { friend class KatePluginSort; public: Kate::MainWindow *win; }; extern "C" { TDE_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(skey ,sdata)); } else { // Case insensitive sort strMLines.insert(std::pair(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(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"