1 /* -------------------------------------------------------------
3 toplevel.cpp (part of The KDE Dictionary Client)
5 Copyright (C) 2000-2001 Christian Gebauer <gebauer@kde.org>
6 (C) by Matthias Hölzer 1998
8 This file is distributed under the Artistic License.
9 See LICENSE for details.
11 -------------------------------------------------------------
13 TopLevel The toplevel widget of Kdict.
15 ------------------------------------------------------------- */
17 #include <qclipboard.h>
19 #include <kstdaccel.h>
20 #include <kstdaction.h>
21 #include <kapplication.h>
22 #include <kstatusbar.h>
25 #include <kedittoolbar.h>
27 #include <dcopclient.h>
32 #include "queryview.h"
33 #include "matchview.h"
38 // cut a QString and add "..."
39 QString
getShortString(QString str
,unsigned int length
)
41 if (str
.length()>length
) {
42 str
.truncate(length
-3);
49 DictInterface
*interface
;
53 TopLevel::TopLevel(QWidget
* parent
, const char* name
)
54 : DCOPObject("KDictIface"), KMainWindow(parent
, name
, WType_TopLevel
),
55 optDlg(0L), setsDlg(0L), stopRef(0)
57 kapp
->dcopClient()->setDefaultObject(objId());
58 kapp
->setMainWidget(this);
60 global
= new GlobalData();
61 global
->topLevel
= this;
63 interface
= new DictInterface();
64 connect(interface
,SIGNAL(infoReady()),SLOT(stratDbChanged()));
65 connect(interface
,SIGNAL(started(const QString
&)),SLOT(clientStarted(const QString
&)));
66 connect(interface
,SIGNAL(stopped(const QString
&)),SLOT(clientStopped(const QString
&)));
68 queryView
= new QueryView(this);
69 connect(queryView
,SIGNAL(defineRequested(const QString
&)),SLOT(define(const QString
&)));
70 connect(queryView
,SIGNAL(matchRequested(const QString
&)),SLOT(match(const QString
&)));
71 connect(queryView
,SIGNAL(clipboardRequested()),SLOT(defineClipboard()));
72 connect(queryView
,SIGNAL(enableCopy(bool)),SLOT(enableCopy(bool)));
73 connect(queryView
,SIGNAL(enablePrintSave()),SLOT(enablePrintSave()));
74 connect(queryView
,SIGNAL(renderingStarted()),SLOT(renderingStarted()));
75 connect(queryView
,SIGNAL(renderingStopped()),SLOT(renderingStopped()));
76 connect(queryView
,SIGNAL(newCaption(const QString
&)),SLOT(newCaption(const QString
&)));
78 matchView
= new MatchView();
79 connect(matchView
,SIGNAL(defineRequested(const QString
&)),SLOT(define(const QString
&)));
80 connect(matchView
,SIGNAL(matchRequested(const QString
&)),SLOT(match(const QString
&)));
81 connect(matchView
,SIGNAL(clipboardRequested()),SLOT(matchClipboard()));
82 connect(matchView
,SIGNAL(windowClosed()),SLOT(toggleMatchListShow()));
83 connect(&resetStatusbarTimer
,SIGNAL(timeout()),SLOT(resetStatusbar()));
90 if (global
->showMatchList
)
91 { // show splitter, html view & match list
92 splitter
= new QSplitter(QSplitter::Horizontal
,this);
93 splitter
->setOpaqueResize( KGlobalSettings::opaqueResize() );
94 queryView
->reparent(splitter
,0,queryView
->pos(),true);
95 matchView
->reparent(splitter
,0,matchView
->pos(),true);
96 setCentralWidget(splitter
);
97 splitter
->setResizeMode(matchView
,QSplitter::KeepSize
);
98 adjustMatchViewSize();
101 { // show only html view
102 setCentralWidget(queryView
);
108 applyMainWindowSettings(KGlobal::config(),"toplevel_options");
109 stratDbChanged(); // fill combos, build menus
111 actQueryCombo
->setFocus(); // place cursor in combobox
115 TopLevel::~TopLevel()
120 void TopLevel::normalStartup()
122 if (global
->defineClipboard
)
126 // ******* DCOP Interface ********************************************************
128 void TopLevel::quit()
130 kdDebug(5004) << "*DCOP call* TopLevel::quit()" << endl
;
131 kapp
->closeAllWindows();
135 void TopLevel::makeActiveWindow()
137 kdDebug(5004) << "*DCOP call* TopLevel::makeActiveWindow()" << endl
;
142 void TopLevel::definePhrase(QString phrase
)
144 kdDebug(5004) << "*DCOP call* TopLevel::definePhrase()" << endl
;
150 void TopLevel::matchPhrase(QString phrase
)
152 kdDebug(5004) << "*DCOP call* TopLevel::matchPhrase()" << endl
;
158 void TopLevel::defineClipboardContent()
160 kdDebug(5004) << "*DCOP call* TopLevel::defineClipboardContent()" << endl
;
166 void TopLevel::matchClipboardContent()
168 kdDebug(5004) << "*DCOP call* TopLevel::matchClipboardContent()" << endl
;
174 QStringList
TopLevel::getDatabases()
176 kdDebug(5004) << "*DCOP call* TopLevel::getDatabases()" << endl
;
177 return global
->databases
;
181 QString
TopLevel::currentDatabase()
183 kdDebug(5004) << "*DCOP call* TopLevel::currentDatabase()" << endl
;
184 return global
->databases
[global
->currentDatabase
];
188 QStringList
TopLevel::getStrategies()
190 kdDebug(5004) << "*DCOP call* TopLevel::getStrategies()" << endl
;
191 return global
->strategies
;
195 QString
TopLevel::currentStrategy()
197 kdDebug(5004) << "*DCOP call* TopLevel::currentStrategy()" << endl
;
198 return global
->strategies
[global
->currentStrategy
];
202 bool TopLevel::setDatabase(QString db
)
204 kdDebug(5004) << "*DCOP call* TopLevel::setDatabase()" << endl
;
206 int newCurrent
= global
->databases
.findIndex(db
);
207 if (newCurrent
== -1)
210 global
->currentDatabase
= newCurrent
;
211 actDbCombo
->setCurrentItem(global
->currentDatabase
);
217 bool TopLevel::setStrategy(QString strategy
)
219 kdDebug(5004) << "*DCOP call* TopLevel::setStrategy()" << endl
;
221 return matchView
->selectStrategy(strategy
);
225 bool TopLevel::historyGoBack()
227 kdDebug(5004) << "*DCOP call* TopLevel::historyGoBack()" << endl
;
229 if (!queryView
->browseBackPossible())
232 queryView
->browseBack();
238 bool TopLevel::historyGoForward()
240 kdDebug(5004) << "*DCOP call* TopLevel::historyGoForward()" << endl
;
242 if (!queryView
->browseForwardPossible())
245 queryView
->browseForward();
250 // *******************************************************************************
252 void TopLevel::define(const QString
&query
)
254 kdDebug(5004) << "TopLevel::define()" << endl
;
255 actQueryCombo
->setEditText(query
);
260 void TopLevel::defineClipboard()
262 kdDebug(5004) << "TopLevel::defineClipboard()" << endl
;
263 kapp
->clipboard()->setSelectionMode(true);
264 QString text
= kapp
->clipboard()->text();
265 if (text
.isEmpty()) {
266 kapp
->clipboard()->setSelectionMode(false);
267 text
= kapp
->clipboard()->text();
273 void TopLevel::match(const QString
&query
)
275 kdDebug(5004) << "TopLevel::match()" << endl
;
276 actQueryCombo
->setEditText(query
);
281 void TopLevel::matchClipboard()
283 kdDebug(5004) << "TopLevel::matchClipboard()" << endl
;
284 kapp
->clipboard()->setSelectionMode(true);
285 QString text
= kapp
->clipboard()->text();
286 if (text
.isEmpty()) {
287 kapp
->clipboard()->setSelectionMode(false);
288 text
= kapp
->clipboard()->text();
294 bool TopLevel::queryClose()
296 kdDebug(5004) << "TopLevel::queryClose()" << endl
;
298 saveMainWindowSettings(KGlobal::config(),"toplevel_options");
300 global
->queryComboCompletionMode
= actQueryCombo
->completionMode();
308 void TopLevel::setupActions()
311 actSave
= KStdAction::save(queryView
, SLOT(saveQuery()), actionCollection());
312 actSave
->setText(i18n("&Save As..."));
313 actSave
->setEnabled(false);
314 actPrint
= KStdAction::print(queryView
, SLOT(printQuery()), actionCollection());
315 actPrint
->setEnabled(false);
316 actStartQuery
= new KAction(i18n("St&art Query"),"reload", 0 , this,
317 SLOT(doDefine()), actionCollection(), "start_query");
318 actStopQuery
= new KAction(i18n("St&op Query"),"stop", 0 , this,
319 SLOT(stopClients()), actionCollection(), "stop_query");
320 actStopQuery
->setEnabled(false);
321 KStdAction::quit(kapp
, SLOT(closeAllWindows()), actionCollection());
324 actCopy
= KStdAction::copy(queryView
, SLOT(copySelection()), actionCollection());
325 actCopy
->setEnabled(false);
326 KStdAction::selectAll(queryView
, SLOT(selectAll()), actionCollection());
327 new KAction(i18n("&Define Clipboard Content"), "define_clip", 0 , this,
328 SLOT(defineClipboard()), actionCollection(), "define_clipboard");
329 new KAction(i18n("&Match Clipboard Content"), 0 , this,
330 SLOT(matchClipboard()), actionCollection(), "match_clipboard");
331 KStdAction::find(queryView
, SLOT(showFindDialog()), actionCollection());
334 actBack
= new KToolBarPopupAction(i18n("&Back"), "back", KStdAccel::shortcut(KStdAccel::Back
),
335 queryView
, SLOT(browseBack()), actionCollection(),"browse_back");
336 actBack
->setDelayed(true);
337 actBack
->setStickyMenu(false);
338 actBack
->setEnabled(false);
339 actForward
= new KToolBarPopupAction(i18n("&Forward"), "forward", KStdAccel::shortcut(KStdAccel::Forward
),
340 queryView
, SLOT(browseForward()), actionCollection(),"browse_forward");
341 actForward
->setDelayed(true);
342 actForward
->setStickyMenu(false);
343 actForward
->setEnabled(false);
344 new KAction(i18n("&Clear History"), 0 , this,
345 SLOT(clearQueryHistory()), actionCollection(), "clear_history");
348 new KAction(i18n("&Get Capabilities"), 0 , interface
,
349 SLOT(updateServer()), actionCollection(), "get_capabilities");
350 new KAction(i18n("Edit &Database Sets..."), "edit", 0 , this,
351 SLOT(showSetsDialog()), actionCollection(), "edit_sets");
352 new KAction(i18n("&Summary"), 0 , interface
,
353 SLOT(showDatabases()), actionCollection(), "db_summary");
354 new KAction(i18n("S&trategy Information"), 0 , interface
,
355 SLOT(showStrategies()), actionCollection(), "strategy_info");
356 new KAction(i18n("&Server Information"), 0 , interface
,
357 SLOT(showInfo()), actionCollection(), "server_info");
360 createStandardStatusBarAction();
361 setStandardToolBarMenuEnabled(true);
363 actShowMatchList
= new KToggleAction(i18n("Show &Match List"), 0 , this,
364 SLOT(toggleMatchListShow()), actionCollection(), "show_match");
365 actShowMatchList
->setCheckedState(i18n("Hide &Match List"));
366 actShowMatchList
->setChecked(global
->showMatchList
);
367 KStdAction::keyBindings(guiFactory(), SLOT(configureShortcuts()),
369 KStdAction::configureToolbars(this, SLOT(slotConfToolbar()), actionCollection());
370 KStdAction::preferences(this, SLOT(showOptionsDialog()), actionCollection());
373 new KAction(i18n("Clear Input Field"), "query_erase", 0 , this,
374 SLOT(clearInput()), actionCollection(), "clear_query");
376 actQueryLabel
= new DictLabelAction(i18n("&Look for:"), actionCollection(), "look_label");
377 actQueryCombo
= new DictComboAction(i18n("Query"), actionCollection(), "query_combo",true,true);
378 connect(actQueryCombo
,SIGNAL(activated(const QString
&)), SLOT(define(const QString
&)));
379 actQueryCombo
->setCompletionMode(global
->queryComboCompletionMode
);
380 actDbLabel
= new DictLabelAction(i18n("&in"), actionCollection(), "in_label");
381 actDbCombo
= new DictComboAction(i18n("Databases"), actionCollection(), "db_combo",false,false);
382 connect(actDbCombo
,SIGNAL(activated(int)),SLOT(databaseSelected(int)));
383 actDefineBtn
= new DictButtonAction(i18n("&Define"), this, SLOT(doDefine()), actionCollection(), "define_btn");
384 actMatchBtn
= new DictButtonAction(i18n("&Match"), this, SLOT(doMatch()), actionCollection(), "match_btn");
386 queryView
->setActions(actBack
,actForward
,actQueryCombo
);
390 void TopLevel::setupStatusBar()
392 statusBar()->insertItem(i18n(" Ready "),0,2);
393 statusBar()->setItemAlignment(0,AlignLeft
| AlignVCenter
);
396 if (global
->authEnabled
)
397 serverInfo
= QString(" %1@%2:%3 ").arg(getShortString(global
->user
,50))
398 .arg(getShortString(global
->server
,50))
401 serverInfo
= QString(" %1:%3 ").arg(getShortString(global
->server
,50))
403 statusBar()->insertItem(serverInfo
, 1,3);
404 statusBar()->setItemAlignment(1,AlignLeft
| AlignVCenter
);
408 void TopLevel::recreateGUI()
410 kdDebug(5004) << "TopLevel::recreateGUI()" << endl
;
411 createGUI("kdictui.rc", false);
412 actQueryCombo
->setList(global
->queryHistory
);
413 actQueryCombo
->clearEdit();
414 actQueryLabel
->setBuddy(actQueryCombo
->widget());
416 actDbCombo
->setList(global
->databases
);
417 actDbCombo
->setCurrentItem(global
->currentDatabase
);
418 actDbLabel
->setBuddy(actDbCombo
->widget());
420 if (actDefineBtn
->widthHint() > actMatchBtn
->widthHint())
421 bwidth
= actDefineBtn
->widthHint();
423 bwidth
= actMatchBtn
->widthHint();
424 actDefineBtn
->setWidth(bwidth
);
425 actMatchBtn
->setWidth(bwidth
);
429 // add text in the query-combobox to the history
430 void TopLevel::addCurrentInputToHistory()
432 QString
text(actQueryCombo
->currentText());
434 // maintain queryHistory
435 global
->queryHistory
.remove(text
); // no double entrys
436 global
->queryHistory
.prepend(text
); // prepend new item
437 while (global
->queryHistory
.count()>global
->maxHistEntrys
) // shorten list
438 global
->queryHistory
.remove(global
->queryHistory
.fromLast());
440 actQueryCombo
->setList(global
->queryHistory
);
441 actQueryCombo
->setCurrentItem(0);
447 // erase text in query-combobox
448 void TopLevel::clearInput()
450 actQueryCombo
->clearEdit();
451 actQueryCombo
->setFocus(); // place cursor in combobox
455 // define text in the combobox
456 void TopLevel::doDefine()
458 QString
text(actQueryCombo
->currentText());
462 addCurrentInputToHistory();
463 actQueryCombo
->selectAll();
464 interface
->define(text
);
469 void TopLevel::doMatch()
471 QString
text(actQueryCombo
->currentText());
475 addCurrentInputToHistory();
476 actQueryCombo
->selectAll();
478 if (!global
->showMatchList
)
480 toggleMatchListShow();
483 matchView
->match(text
);
484 setCaption(getShortString(text
.simplifyWhiteSpace(),70));
489 void TopLevel::stopClients()
496 // rebuild history menu on demand
497 void TopLevel::buildHistMenu()
499 unplugActionList("history_items");
501 historyActionList
.setAutoDelete(true);
502 historyActionList
.clear();
505 while ((i
<10)&&(i
<global
->queryHistory
.count())) {
506 historyActionList
.append( new KAction(getShortString(global
->queryHistory
[i
],70), 0, this, SLOT(queryHistMenu()),
507 (QObject
*)0, global
->queryHistory
[i
].utf8().data()) );
511 plugActionList("history_items", historyActionList
);
515 // process a query via the history menu
516 void TopLevel::queryHistMenu()
518 QCString name
= sender()->name();
520 define(QString::fromUtf8(name
));
524 void TopLevel::clearQueryHistory()
526 global
->queryHistory
.clear();
527 actQueryCombo
->clear();
532 // fill combos, rebuild menus
533 void TopLevel::stratDbChanged()
535 actDbCombo
->setList(global
->databases
);
536 actDbCombo
->setCurrentItem(global
->currentDatabase
);
537 matchView
->updateStrategyCombo();
539 unplugActionList("db_detail");
541 dbActionList
.setAutoDelete(true);
542 dbActionList
.clear();
544 for (unsigned int i
=0;i
<global
->serverDatabases
.count();i
++)
545 dbActionList
.append( new KAction(global
->serverDatabases
[i
], 0, this, SLOT(dbInfoMenuClicked()),
546 (QObject
*)0, global
->serverDatabases
[i
].utf8().data()) );
548 plugActionList("db_detail", dbActionList
);
552 void TopLevel::dbInfoMenuClicked()
554 QCString name
= sender()->name();
556 interface
->showDbInfo(name
);
560 void TopLevel::databaseSelected(int num
)
562 global
->currentDatabase
= num
;
566 void TopLevel::enableCopy(bool selected
)
568 actCopy
->setEnabled(selected
);
572 void TopLevel::enablePrintSave()
574 actSave
->setEnabled(true);
575 actPrint
->setEnabled(true);
579 void TopLevel::clientStarted(const QString
&message
)
581 statusBar()->changeItem(message
,0);
582 resetStatusbarTimer
.stop();
584 actStopQuery
->setEnabled(stopRef
>0); // enable stop-icon
585 kapp
->setOverrideCursor(waitCursor
);
589 void TopLevel::clientStopped(const QString
&message
)
591 statusBar()->changeItem(message
,0);
592 resetStatusbarTimer
.start(4000);
595 actStopQuery
->setEnabled(stopRef
>0); // disable stop-icon
596 kapp
->restoreOverrideCursor();
600 void TopLevel::resetStatusbar()
602 resetStatusbarTimer
.stop();
603 statusBar()->changeItem(i18n(" Ready "),0);
607 void TopLevel::renderingStarted()
610 actStopQuery
->setEnabled(stopRef
>0); // disable stop-icon
611 kapp
->setOverrideCursor(waitCursor
);
615 void TopLevel::renderingStopped()
619 actStopQuery
->setEnabled(stopRef
>0); // disable stop-icon
620 kapp
->restoreOverrideCursor();
624 void TopLevel::newCaption(const QString
&s
)
629 void TopLevel::toggleMatchListShow()
632 if (global
->showMatchList
) // list is visible -> hide it
634 global
->showMatchList
= false;
635 queryView
->reparent(this,0,queryView
->pos(),true);
636 matchView
->reparent(this,0,matchView
->pos(),true);
639 setCentralWidget(queryView
);
641 else // list is not visible -> show it
643 global
->showMatchList
= true;
644 splitter
= new QSplitter(QSplitter::Horizontal
,this);
645 splitter
->setOpaqueResize( KGlobalSettings::opaqueResize() );
646 setCentralWidget(splitter
);
648 queryView
->reparent(splitter
,0,queryView
->pos(),true);
649 matchView
->reparent(splitter
,0,matchView
->pos(),true);
650 splitter
->setResizeMode(matchView
,QSplitter::KeepSize
);
651 adjustMatchViewSize();
654 actShowMatchList
->setChecked(global
->showMatchList
);
658 void TopLevel::saveMatchViewSize()
660 if (global
->showMatchList
)
662 global
->splitterSizes
= splitter
->sizes();
667 void TopLevel::adjustMatchViewSize()
669 if (global
->splitterSizes
.count()==2)
671 splitter
->setSizes(global
->splitterSizes
);
676 void TopLevel::slotConfToolbar()
678 saveMainWindowSettings(KGlobal::config(),"toplevel_options");
679 KEditToolbar
dlg(actionCollection(), "kdictui.rc");
680 connect(&dlg
,SIGNAL( newToolbarConfig() ), this, SLOT( slotNewToolbarConfig() ));
685 void TopLevel::slotNewToolbarConfig()
688 applyMainWindowSettings(KGlobal::config(),"toplevel_options");
689 buildHistMenu(); // actionlists must be inserted
694 void TopLevel::showSetsDialog()
697 setsDlg
= new DbSetsDialog(this);
698 connect(setsDlg
,SIGNAL(setsChanged()),this,SLOT(setsChanged()));
699 connect(setsDlg
,SIGNAL(dialogClosed()),this,SLOT(hideSetsDialog()));
702 KWin::activateWindow(setsDlg
->winId());
707 void TopLevel::hideSetsDialog()
710 setsDlg
->delayedDestruct();
716 void TopLevel::setsChanged()
718 actDbCombo
->setList(global
->databases
);
719 actDbCombo
->setCurrentItem(global
->currentDatabase
);
723 void TopLevel::showOptionsDialog()
726 optDlg
= new OptionsDialog(this);
727 connect(optDlg
,SIGNAL(optionsChanged()),this,SLOT(optionsChanged()));
728 connect(optDlg
,SIGNAL(finished()),this,SLOT(hideOptionsDialog()));
731 KWin::activateWindow(optDlg
->winId());
736 void TopLevel::hideOptionsDialog()
739 optDlg
->delayedDestruct();
745 void TopLevel::optionsChanged()
748 if (global
->authEnabled
)
749 serverInfo
= QString(" %1@%2:%3 ").arg(getShortString(global
->user
,50))
750 .arg(getShortString(global
->server
,50))
753 serverInfo
= QString(" %1:%3 ").arg(getShortString(global
->server
,50))
755 statusBar()->changeItem(serverInfo
,1);
756 interface
->serverChanged(); // inform client
757 queryView
->optionsChanged(); // inform html-view
760 void TopLevel::raiseWindow()
762 // Bypass focus stealing prevention
763 kapp
->updateUserTimestamp();
765 KWin::WindowInfo info
= KWin::windowInfo( winId() );
767 if ( !info
.isOnCurrentDesktop() )
769 KWin::setOnDesktop( winId(), KWin::currentDesktop() );
772 KWin::activateWindow(winId());
776 //--------------------------------
778 #include "toplevel.moc"