Add common code for buddy icon retrieving and remove the old one.
[kdenetwork.git] / kdict / queryview.cpp
blobac3643a98c98af65874a8698427c6dc9bfb91ee8
1 /* -------------------------------------------------------------
3 queryview.cpp (part of The KDE Dictionary Client)
5 Copyright (C) 2000-2001 Christian Gebauer <gebauer@kde.org>
7 This file is distributed under the Artistic License.
8 See LICENSE for details.
10 -------------------------------------------------------------
12 BrowseData data structure used for caching definitions
13 DictHTMLPart handling of middle mouse button clicks
14 QueryView widget that displays the definitions
16 ------------------------------------------------------------- */
18 #include <qclipboard.h>
19 #include <qtimer.h>
20 //Added by qt3to4:
21 #include <QTextStream>
23 #include <kfiledialog.h>
24 #include <ktempfile.h>
25 #include <kio/netaccess.h>
26 #include <kcursor.h>
27 #include <kmenu.h>
28 #include <kmessagebox.h>
29 #include <klocale.h>
30 #include <khtml_events.h>
31 #include <khtmlview.h>
32 #include <kactioncollection.h>
33 #include <ktoolbarpopupaction.h>
34 #include "actions.h"
35 #include "options.h"
36 #include "dict.h"
37 #include "queryview.h"
38 #include <kapplication.h>
39 #include <kiconloader.h>
40 #include <ktoolinvocation.h>
43 //******** SaveHelper *******************************************
45 QString SaveHelper::lastPath;
47 SaveHelper::SaveHelper(const QString &saveName, const QString &filter, QWidget *parent)
48 : p_arent(parent), s_aveName(saveName), f_ilter(filter), file(0), tmpFile(0)
53 SaveHelper::~SaveHelper()
55 if (file) { // local filesystem, just close the file
56 delete file;
57 } else
58 if (tmpFile) { // network location, initiate transaction
59 tmpFile->close();
60 if (KIO::NetAccess::upload(tmpFile->name(),url, p_arent) == false)
61 KMessageBox::error(global->topLevel, i18n("Unable to save remote file."));
62 tmpFile->unlink(); // delete temp file
63 delete tmpFile;
68 QFile* SaveHelper::getFile(const QString &dialogTitle)
70 url = KFileDialog::getSaveURL(lastPath+s_aveName,f_ilter,p_arent,dialogTitle);
72 if (url.isEmpty())
73 return 0;
75 lastPath = url.url(KUrl::RemoveTrailingSlash);
76 lastPath.truncate(lastPath.length()-url.fileName().length());
78 if (url.isLocalFile()) {
79 if (QFileInfo(url.path()).exists() &&
80 (KMessageBox::warningContinueCancel(global->topLevel,
81 i18n("A file named %1 already exists.\nDo you want to replace it?", url.path()),
82 dialogTitle, i18n("&Replace")) != KMessageBox::Continue)) {
83 return 0;
86 file = new QFile(url.path());
87 if(!file->open(QIODevice::WriteOnly)) {
88 KMessageBox::error(global->topLevel, i18n("Unable to save file."));
89 delete file;
90 file = 0;
92 return file;
93 } else {
94 tmpFile = new KTempFile();
95 if (tmpFile->status()!=0)
96 KMessageBox::error(global->topLevel, i18n("Unable to create temporary file.")); {
97 delete tmpFile;
98 tmpFile = 0;
99 return 0;
101 return tmpFile->file();
106 //**** BrowseData ****************************************************
109 BrowseData::BrowseData(const QString &Nhtml, const QString &NqueryText)
110 : html(Nhtml),queryText(NqueryText),xPos(0),yPos(0)
114 //********* DictHTMLPart ******************************************
116 DictHTMLPart::DictHTMLPart(QWidget *parentWidget, const char *widgetname)
117 : KHTMLPart(parentWidget/*,widgetname*/)
121 DictHTMLPart::~DictHTMLPart()
125 void DictHTMLPart::khtmlMouseReleaseEvent(khtml::MouseReleaseEvent *event)
127 if (event->qmouseEvent()->button()==Qt::MidButton)
128 emit(middleButtonClicked());
129 else
130 KHTMLPart::khtmlMouseReleaseEvent(event);
134 //********* QueryView ******************************************
137 QueryView::QueryView(QWidget *_parent)
138 : Q3VBox( _parent), actBack(0L), actForward(0L), actQueryCombo(0L), browsePos(0), isRendering(false)
140 browseList.setAutoDelete(true);
142 part=new DictHTMLPart(this);
143 part->setDNDEnabled(false);
144 part->setJScriptEnabled(false);
145 part->setJavaEnabled(false);
146 part->setURLCursor(KCursor::handCursor());
147 setFocusPolicy(Qt::NoFocus);
148 connect(part, SIGNAL(completed()), SLOT(partCompleted()));
149 connect(part, SIGNAL(middleButtonClicked()), SLOT(middleButtonClicked()));
150 rightBtnMenu = new KMenu(this);
151 connect(part,SIGNAL(popupMenu(const QString &, const QPoint &)),this,SLOT(buildPopupMenu(const QString &, const QPoint &)));
152 connect(part->browserExtension(),SIGNAL(openURLRequest(const KUrl &,const KParts::URLArgs &)),
153 this,SLOT(slotURLRequest(const KUrl &,const KParts::URLArgs &)));
154 connect(part->browserExtension(),SIGNAL(enableAction(const char *,bool)),this,SLOT(enableAction(const char *,bool)));
155 QTimer::singleShot( 0, this, SLOT(optionsChanged()) );
156 connect(interface,SIGNAL(resultReady(const QString &, const QString &)), SLOT(resultReady(const QString &, const QString &)));
160 QueryView::~QueryView()
164 void QueryView::setActions(KToolBarPopupAction* NactBack, KToolBarPopupAction* NactForward, DictComboAction* NactQueryCombo)
166 actBack = NactBack;
167 connect(actBack->popupMenu(),SIGNAL(activated(int)),SLOT(browseBack(int)));
168 actForward = NactForward;
169 connect(actForward->popupMenu(),SIGNAL(activated(int)),SLOT(browseForward(int)));
170 actQueryCombo = NactQueryCombo;
174 bool QueryView::browseBackPossible() const
176 return (browsePos > 0)? true:false;
180 bool QueryView::browseForwardPossible() const
182 return (browsePos+1 < browseList.count()) ? true:false;
186 void QueryView::optionsChanged()
188 saveCurrentResultPos();
190 currentHTMLHeader = QString("<html><head><style type=\"text/css\">\n");
191 currentHTMLHeader += QString("body { background-color:%1; color:%2; }\n").arg(global->backgroundColor().name()).arg(global->textColor().name());
192 currentHTMLHeader += QString("a:link, a:active { color:%1; text-decoration:none; }\n").arg(global->linksColor().name());
193 currentHTMLHeader += QString("a:visited { color:%1; text-decoration:none; }\n").arg(global->visitedLinksColor().name());
194 currentHTMLHeader += QString("a:hover { color:%1; text-decoration:underline; }\n").arg(global->linksColor().name());
195 currentHTMLHeader += QString("p.heading { margin-left:0mm; margin-top:2mm; margin-bottom:2mm; padding:1mm; background-color:%1; color:%2; font-family:%3; font-size:%4pt; ").arg(global->headingsBackgroundColor().name()).arg(global->headingsTextColor().name()).arg(global->headingsFont().family()).arg(global->headingsFont().pointSize());
196 if (global->headingsFont().italic())
197 currentHTMLHeader += QString("font-style:italic; ");
198 if (global->headingsFont().bold())
199 currentHTMLHeader += QString("font-weight:bold; ");
200 currentHTMLHeader += QString("}\n");
201 currentHTMLHeader += QString("p.definition { margin-left:1.5mm; margin-top:2mm; margin-bottom:2mm;}\n");
202 currentHTMLHeader += QString("table { margin-left:1.5mm; margin-top:2mm; margin-bottom:2mm;}\n");
203 currentHTMLHeader += QString("pre { font-family:%1; font-size:%2pt; ").arg(global->textFont().family()).arg(global->textFont().pointSize());
204 if (global->textFont().italic())
205 currentHTMLHeader += QString("font-style:italic; ");
206 if (global->textFont().bold())
207 currentHTMLHeader += QString("font-weight:bold; ");
208 currentHTMLHeader += QString("}\n");
209 currentHTMLHeader += QString("</style></head>\n");
211 showResult(); // apply changes directly
215 void QueryView::stop()
217 if (isRendering == true) {
218 part->closeURL();
219 isRendering = false;
220 emit(renderingStopped());
225 // print current result
226 void QueryView::printQuery()
228 part->view()->print();
232 // save the current result in an .html file
233 void QueryView::saveQuery()
235 if (!browseList.isEmpty()) {
236 BrowseData* brw = browseList.at(browsePos);
237 QString fName = brw->queryText+".html";
238 fName.replace(QRegExp("[\\s/]"),"_");
239 SaveHelper helper(fName,"*.html",global->topLevel);
240 QFile *file = helper.getFile(QString::null);
242 if (file) {
243 QTextStream stream(file);
244 stream.setEncoding(QTextStream::Locale);
245 stream << currentHTMLHeader+brw->html;
251 void QueryView::browseBack()
253 if (browseBackPossible()) {
254 saveCurrentResultPos();
255 browsePos--;
256 actQueryCombo->setEditText(browseList.at(browsePos)->queryText);
257 showResult();
258 updateBrowseActions();
263 void QueryView::browseForward()
265 if (browseForwardPossible()) {
266 saveCurrentResultPos();
267 browsePos++;
268 actQueryCombo->setEditText(browseList.at(browsePos)->queryText);
269 showResult();
270 updateBrowseActions();
275 void QueryView::selectAll()
277 part->selectAll();
281 void QueryView::copySelection()
283 kapp->clipboard()->setText(part->selectedText());
287 void QueryView::showFindDialog()
289 KAction *act = part->actionCollection()->action("find");
290 if (act)
291 act->activate();
295 void QueryView::paletteChange ( const QPalette & )
298 optionsChanged();
302 void QueryView::fontChange ( const QFont & )
304 optionsChanged();
308 void QueryView::saveCurrentResultPos()
310 if (!browseList.isEmpty()) {
311 browseList.at(browsePos)->xPos = part->view()->contentsX();
312 browseList.at(browsePos)->yPos = part->view()->contentsY();
317 void QueryView::showResult()
319 if (!isRendering) {
320 isRendering = true;
321 emit(renderingStarted());
324 part->begin();
325 if (browseList.isEmpty()) {
326 part->write(currentHTMLHeader+"<body></body></html>");
327 part->end();
328 } else {
329 BrowseData* brw = browseList.at(browsePos);
330 emit(newCaption(getShortString(brw->queryText.simplified(),70)));
331 part->write(currentHTMLHeader+brw->html);
332 part->end();
333 part->view()->setFocus();
338 void QueryView::resultReady(const QString &result, const QString &query)
340 BrowseData* brw = new BrowseData(result,query);
342 if (browseList.isEmpty()) {
343 browsePos = 0;
344 browseList.append(brw);
345 } else {
346 saveCurrentResultPos();
347 while (browseList.count()>browsePos+1)
348 browseList.removeLast();
349 browseList.append(brw);
350 browsePos++;
351 while (browseList.count()>global->maxBrowseListEntrys) {
352 browseList.removeFirst();
353 browsePos--;
357 showResult();
358 emit(enablePrintSave());
359 actQueryCombo->selectAll();
360 updateBrowseActions();
364 void QueryView::partCompleted()
366 if (!browseList.isEmpty())
367 part->view()->setContentsPos(browseList.at(browsePos)->xPos,browseList.at(browsePos)->yPos);
368 if (isRendering) {
369 emit(renderingStopped());
370 isRendering = false;
375 void QueryView::slotURLRequest (const KUrl &url, const KParts::URLArgs &)
377 QString type = url.host();
378 QString urlText = url.prettyUrl();
379 urlText.remove(0,8+type.length());
381 if (type.length()) { // valid url
382 if(type=="define")
383 emit(defineRequested(urlText));
384 if(type=="dbinfo")
385 interface->showDbInfo(urlText.utf8());
386 if(type=="realhttp")
387 KToolInvocation::invokeBrowser("http://"+urlText);
388 if(type=="realftp")
389 KToolInvocation::invokeBrowser("ftp://"+urlText);
394 void QueryView::middleButtonClicked()
396 emit(clipboardRequested());
400 // construct the right-mouse-button-popup-menu on demand
401 void QueryView::buildPopupMenu(const QString &url, const QPoint &point)
403 rightBtnMenu->clear();
405 if (!url.isEmpty()) { // menuitem if mouse is over link
406 KUrl u(url);
407 QString type = u.host();
408 popupLink = u.prettyUrl();
409 popupLink.remove(0,8+type.length());
411 if (type.length()) { // valid url
412 if(type=="define") {
413 rightBtnMenu->insertItem(i18n("Define &Synonym"),
414 this,SLOT(popupDefineLink()));
415 rightBtnMenu->insertItem(i18n("M&atch Synonym"),
416 this,SLOT(popupMatchLink()));
417 rightBtnMenu->insertSeparator();
419 if(type=="dbinfo") {
420 rightBtnMenu->insertItem(i18n("D&atabase Information"),this,SLOT(popupDbInfo()));
421 rightBtnMenu->insertSeparator();
423 if(type=="realhttp") {
424 popupLink.prepend("http://");
425 rightBtnMenu->insertItem(SmallIcon("fileopen"),
426 i18n("&Open Link"),
427 this,SLOT(popupOpenLink()));
428 rightBtnMenu->insertSeparator();
430 if(type=="realftp") {
431 popupLink.prepend("ftp://");
432 rightBtnMenu->insertItem(SmallIcon("fileopen"),
433 i18n("&Open Link"),
434 this,SLOT(popupOpenLink()));
435 rightBtnMenu->insertSeparator();
440 if (part->hasSelection()) {
441 popupSelect = part->selectedText();
442 rightBtnMenu->insertItem(i18n("&Define Selection"),
443 this,SLOT(popupDefineSelect()));
444 rightBtnMenu->insertItem(i18n("&Match Selection"),
445 this,SLOT(popupMatchSelect()));
446 rightBtnMenu->insertSeparator();
447 } else {
448 QString text = kapp->clipboard()->text(QClipboard::Clipboard);
449 if (text.isEmpty()) {
450 text = kapp->clipboard()->text(QClipboard::Selection);
452 if (!text.isEmpty()) {
453 popupSelect = QApplication::clipboard()->text();
454 rightBtnMenu->insertItem(SmallIcon("define_clip"),
455 i18n("&Define Clipboard Content"),
456 this,SLOT(popupDefineSelect()));
457 rightBtnMenu->insertItem(i18n("&Match Clipboard Content"),
458 this,SLOT(popupMatchSelect()));
459 rightBtnMenu->insertSeparator();
463 int ID;
465 if (browseBackPossible()) { // if possible, show string
466 if (browseList.at(browsePos-1)->queryText.isEmpty())
467 rightBtnMenu->insertItem(SmallIcon("back"),
468 i18n("&Back: Information"),
469 this,SLOT(browseBack()));
470 else
471 rightBtnMenu->insertItem(SmallIcon("back"),
472 i18n("&Back: '%1'", getShortString(browseList.at(browsePos-1)->queryText,25)),
473 this,SLOT(browseBack()));
474 } else {
475 ID = rightBtnMenu->insertItem(SmallIcon("back"), i18n("&Back"), this, SLOT(browseBack()));
476 rightBtnMenu->setItemEnabled(ID,false);
479 if (browseForwardPossible()) { // if possible, show string
480 if (browseList.at(browsePos+1)->queryText.isEmpty())
481 rightBtnMenu->insertItem(SmallIcon("forward"),
482 i18n("&Forward: Information"),
483 this,SLOT(browseForward()));
484 else
485 rightBtnMenu->insertItem(SmallIcon("forward"),
486 i18n("&Forward: '%1'", getShortString(browseList.at(browsePos+1)->queryText,25)),
487 this,SLOT(browseForward()));
488 } else {
489 ID = rightBtnMenu->insertItem(SmallIcon("forward"),i18n("&Forward"),this,SLOT(browseForward()));
490 rightBtnMenu->setItemEnabled(ID,false);
493 rightBtnMenu->popup(point);
497 void QueryView::popupDefineLink()
499 emit(defineRequested(popupLink));
503 void QueryView::popupMatchLink()
505 emit(matchRequested(popupLink));
509 void QueryView::popupOpenLink()
511 KToolInvocation::invokeBrowser(popupLink);
515 void QueryView::popupDefineSelect()
517 emit(defineRequested(popupSelect));
521 void QueryView::popupMatchSelect()
523 emit(matchRequested(popupSelect));
527 void QueryView::popupDbInfo()
530 interface->showDbInfo(popupLink.utf8());
534 void QueryView::enableAction(const char * name, bool enabled)
536 if (!strcmp(name,"copy"))
537 emit(enableCopy(enabled));
541 void QueryView::browseBack(int index)
543 int x = browsePos-index;
544 if (x>=0) {
545 saveCurrentResultPos();
546 browsePos = x;
547 actQueryCombo->setEditText(browseList.at(browsePos)->queryText);
548 showResult();
549 QTimer::singleShot(0, this, SLOT(updateBrowseActions())); // don't clear the menu in this slot
554 void QueryView::browseForward(int index)
556 int x = browsePos+index;
557 if (x < (int)(browseList.count())) {
558 saveCurrentResultPos();
559 browsePos = x;
560 actQueryCombo->setEditText(browseList.at(browsePos)->queryText);
561 showResult();
562 QTimer::singleShot(0, this, SLOT(updateBrowseActions())); // don't clear the menu in this slot
567 void QueryView::updateBrowseActions()
569 if (browseBackPossible()) {
570 actBack->setEnabled(true);
571 if (browseList.at(browsePos-1)->queryText.isEmpty())
572 actBack->setText(i18n("&Back: Information"));
573 else
574 actBack->setText(i18n("&Back: '%1'", getShortString(browseList.at(browsePos-1)->queryText,25)));
576 actBack->popupMenu()->clear();
577 int i = browsePos-1;
578 int num = 1;
579 QString s;
580 while ((i>=0)&&(num<=10)) {
581 s = browseList.at(i)->queryText;
582 if (s.isEmpty()) s = i18n("Information");
583 actBack->popupMenu()->insertItem(s,num);
584 num++;
585 i--;
587 } else {
588 actBack->setEnabled(false);
589 actBack->setText(i18n("&Back"));
590 actBack->popupMenu()->clear();
593 if (browseForwardPossible()) {
594 actForward->setEnabled(true);
595 if (browseList.at(browsePos+1)->queryText.isEmpty())
596 actForward->setText(i18n("&Forward: Information"));
597 else
598 actForward->setText(i18n("&Forward: '%1'", getShortString(browseList.at(browsePos+1)->queryText,25)));
600 actForward->popupMenu()->clear();
601 int i = browsePos+1;
602 int num = 1;
603 QString s;
604 while ((i<(int)(browseList.count()))&&(num<=10)) {
605 s = browseList.at(i)->queryText;
606 if (s.isEmpty()) s = i18n("Information");
607 actForward->popupMenu()->insertItem(s,num);
608 num++;
609 i++;
611 } else {
612 actForward->setEnabled(false);
613 actForward->setText(i18n("&Forward"));
614 actForward->popupMenu()->clear();
618 //--------------------------------
620 #include "queryview.moc"