summaryrefslogtreecommitdiffstats
path: root/src/app/Dialogs/popularurls.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/app/Dialogs/popularurls.cpp')
-rw-r--r--src/app/Dialogs/popularurls.cpp307
1 files changed, 307 insertions, 0 deletions
diff --git a/src/app/Dialogs/popularurls.cpp b/src/app/Dialogs/popularurls.cpp
new file mode 100644
index 0000000..9fe2184
--- /dev/null
+++ b/src/app/Dialogs/popularurls.cpp
@@ -0,0 +1,307 @@
+#include <tdemessagebox.h>
+#include <tdelocale.h>
+#include <tqpushbutton.h>
+#include <tdelistview.h>
+#include <kiconloader.h>
+#include <tdelistviewsearchline.h>
+#include <tqheader.h>
+#include <tqlayout.h>
+#include <tqlabel.h>
+#include <tdetoolbarbutton.h>
+#include "../krusader.h"
+#include "../krslots.h"
+#include "popularurls.h"
+
+#define STARTING_RANK 20
+#define INCREASE 2
+#define DECREASE 1
+
+PopularUrls::PopularUrls(TQObject *parent, const char *name) : TQObject(parent, name),
+ head(0), tail(0), count(0) {
+ dlg = new PopularUrlsDlg();
+}
+
+PopularUrls::~PopularUrls() {
+ clearList();
+ delete dlg;
+}
+
+void PopularUrls::clearList() {
+ if (head) {
+ UrlNodeP p=head, tmp;
+ while (p) {
+ tmp = p;
+ p=p->next;
+ delete tmp;
+ }
+ }
+ ranks.clear();
+ head = tail = 0;
+}
+
+void PopularUrls::save() {
+ TDEConfigGroupSaver svr(krConfig, "Private");
+ // prepare the string list containing urls and int list with ranks
+ TQStringList urlList;
+ TQValueList<int> rankList;
+ UrlNodeP p = head;
+ while (p) {
+ urlList << p->url.prettyURL();
+ rankList << p->rank;
+ p = p->next;
+ }
+ krConfig->writeEntry("PopularUrls", urlList);
+ krConfig->writeEntry("PopularUrlsRank", rankList);
+}
+
+void PopularUrls::load() {
+ TDEConfigGroupSaver svr(krConfig, "Private");
+ TQStringList urlList = krConfig->readListEntry("PopularUrls");
+ TQValueList<int> rankList = krConfig->readIntListEntry("PopularUrlsRank");
+ if (urlList.count() != rankList.count()) {
+ KMessageBox::error(krApp, i18n("Saved 'Popular Urls' are invalid. List will be cleared"));
+ return;
+ }
+ clearList();
+ count = 0;
+ // iterate through both lists and
+ TQStringList::Iterator uit;
+ TQValueList<int>::Iterator rit;
+ for (uit=urlList.begin(), rit=rankList.begin(); uit!=urlList.end() && rit!=rankList.end(); ++uit, ++rit) {
+ UrlNodeP node = new UrlNode;
+ node->url = KURL::fromPathOrURL( *uit );
+ node->rank = *rit;
+ appendNode(node);
+ ranks.insert(*uit, node);
+ }
+}
+
+
+// returns a url list with the 'max' top popular urls
+KURL::List PopularUrls::getMostPopularUrls(int max) {
+ // get at most 'max' urls
+ KURL::List list;
+ UrlNodeP p = head;
+ int tmp = 0;
+ if (maxUrls < max) max = maxUrls; // don't give more than maxUrls
+ while (p && tmp < max) {
+ list << p->url;
+ p = p->next;
+ ++tmp;
+ }
+
+ return list;
+}
+
+// adds a url to the list, or increase rank of an existing url, making
+// sure to bump it up the list if needed
+void PopularUrls::addUrl(const KURL& url) {
+ KURL tmpurl = url;
+ tmpurl.adjustPath(1); // make a uniform trailing slash policy
+ UrlNodeP pnode;
+
+ decreaseRanks();
+ if (!head) { // if the list is empty ... (assumes dict to be empty as well)
+ pnode = new UrlNode;
+ pnode->rank = STARTING_RANK;
+ pnode->url = tmpurl;
+ appendNode(pnode);
+ ranks.insert(tmpurl.url(), head);
+ } else {
+ pnode = ranks.find(tmpurl.url());
+ if (!pnode) { // is the added url new? if so, append it
+ pnode = new UrlNode;
+ pnode->rank = STARTING_RANK;
+ pnode->url = tmpurl;
+ appendNode(pnode);
+ ranks.insert(tmpurl.url(), pnode);
+ } else {
+ pnode->rank += INCREASE;
+ }
+ }
+
+ // do we need to change location for this one?
+ relocateIfNeeded(pnode);
+
+ // too many urls?
+ if (count > maxUrls) removeNode(tail);
+
+ //dumpList();
+}
+
+// checks if 'node' needs to be bumped-up the ranking list and does it if needed
+void PopularUrls::relocateIfNeeded(UrlNodeP node) {
+ if (node->prev && (node->prev->rank < node->rank)) {
+ // iterate until we find the correct place to put it
+ UrlNodeP tmp = node->prev->prev;
+ while (tmp) {
+ if (tmp->rank >= node->rank)
+ break; // found it!
+ else tmp = tmp->prev;
+ }
+ // now, if tmp isn't null, we need to move node to tmp->next
+ // else move it to become head
+ removeNode(node);
+ insertNode(node, tmp);
+ }
+}
+
+
+// iterate over the list, decreasing each url's rank
+// this is very naive, but a 1..30 for loop is acceptable (i hope)
+void PopularUrls::decreaseRanks() {
+ if (head) {
+ UrlNodeP p=head;
+ while (p) {
+ if (p->rank-DECREASE>=0)
+ p->rank -= DECREASE;
+ else p->rank = 0;
+ p=p->next;
+ }
+ }
+}
+
+// removes a node from the list, but doesn't free memory!
+// note: this will be buggy in case the list becomes empty (which should never happen)
+void PopularUrls::removeNode(UrlNodeP node) {
+ if (node->prev) {
+ if (tail == node) tail = node->prev;
+ node->prev->next = node->next;
+ }
+ if (node->next) {
+ if (head == node) head = node->next;
+ node->next->prev = node->prev;
+ }
+ --count;
+}
+
+void PopularUrls::insertNode(UrlNodeP node, UrlNodeP after) {
+ if (!after) { // make node head
+ node->next = head;
+ node->prev = 0;
+ head->prev = node;
+ head = node;
+ } else {
+ if (tail == after) tail = node;
+ node->prev = after;
+ node->next = after->next;
+ if( node->next ) {
+ after->next->prev = node;
+ after->next = node;
+ }
+ }
+ ++count;
+}
+
+// appends 'node' to the end of the list, collecting garbage if needed
+void PopularUrls::appendNode(UrlNodeP node) {
+ if (!tail) { // creating the first element
+ head = tail = node;
+ node->prev = node->next = 0;
+ } else {
+ node->next = 0;
+ node->prev = tail;
+ tail->next = node;
+ tail = node;
+ }
+ ++count;
+}
+
+void PopularUrls::dumpList() {
+ UrlNodeP p = head;
+ printf("====start %d====\n",count);
+ while (p) {
+ printf("%d : %s\n", p->rank, p->url.url().latin1());
+ p = p->next;
+ }
+ fflush(stdout);
+}
+
+void PopularUrls::showDialog() {
+ KURL::List list = getMostPopularUrls(maxUrls);
+ dlg->run(list);
+ if (dlg->result() == -1) return;
+ SLOTS->refresh(list[dlg->result()]);
+ //printf("running %s\n", list[dlg->result()].url().latin1());fflush(stdout);
+}
+
+// ===================================== PopularUrlsDlg ======================================
+PopularUrlsDlg::PopularUrlsDlg():
+ KDialogBase(Plain, i18n("Popular Urls"), Close, KDialogBase::NoDefault, krApp) {
+ TQGridLayout *layout = new TQGridLayout( plainPage(), 0, KDialog::spacingHint() );
+
+ // listview to contain the urls
+ urls = new TDEListView(plainPage());
+ urls->header()->hide();
+ urls->addColumn("");
+ urls->setSorting(-1);
+ urls->setVScrollBarMode(TQScrollView::AlwaysOn);
+
+ // quick search
+ TQToolButton *btn = new TQToolButton(plainPage());
+ btn->setIconSet(SmallIcon("locationbar_erase"));
+ search = new TDEListViewSearchLine(plainPage(), urls);
+ search->setTrapReturnKey(true);
+ TQLabel *lbl = new TQLabel(search, i18n(" &Search: "), plainPage());
+
+ layout->addWidget(btn,0,0);
+ layout->addWidget(lbl,0,1);
+ layout->addWidget(search,0,2);
+ layout->addMultiCellWidget(urls,1,1,0,2);
+ setMaximumSize(600, 500);
+
+ setTabOrder(search, urls);
+ setTabOrder(urls, actionButton(Close));
+
+ connect(urls, TQ_SIGNAL(executed(TQListViewItem*)),
+ this, TQ_SLOT(slotItemSelected(TQListViewItem*)));
+ connect(urls, TQ_SIGNAL(returnPressed(TQListViewItem*)),
+ this, TQ_SLOT(slotItemSelected(TQListViewItem*)));
+ connect(btn, TQ_SIGNAL(clicked()), search, TQ_SLOT(clear()));
+ connect(search, TQ_SIGNAL(returnPressed(const TQString&)),
+ this, TQ_SLOT(slotSearchReturnPressed(const TQString&)));
+}
+
+void PopularUrlsDlg::slotItemSelected(TQListViewItem *it) {
+ selection = urls->itemIndex(it);
+ accept();
+}
+
+void PopularUrlsDlg::slotSearchReturnPressed(const TQString&) {
+ urls->setFocus();
+ // select the first visible item
+ TQListViewItemIterator it( urls );
+ while ( it.current() ) {
+ if ( it.current()->isVisible() ) {
+ urls->setSelected(it.current(), true);
+ urls->setCurrentItem(it.current());
+ break;
+ } else ++it;
+ }
+}
+
+PopularUrlsDlg::~PopularUrlsDlg() {
+ delete search;
+ delete urls;
+}
+
+void PopularUrlsDlg::run(KURL::List list) {
+ // populate the listview
+ urls->clear();
+ KURL::List::Iterator it;
+ for (it = list.begin(); it!=list.end(); ++it) {
+ TDEListViewItem *item = new TDEListViewItem(urls, urls->lastItem());
+ item->setText(0, (*it).isLocalFile() ? (*it).path() : (*it).prettyURL());
+ item->setPixmap(0, (*it).isLocalFile() ? SmallIcon("folder") : SmallIcon("folder_html"));
+ }
+ //urls->setCurrentItem(urls->firstChild());
+ //urls->setSelected(urls->firstChild(), true);
+ setMinimumSize(urls->sizeHint().width()+45, 400);
+
+ search->clear();
+ search->setFocus();
+ selection = -1;
+ exec();
+}
+
+#include "popularurls.moc"