You are saving a file with many images, which causes Tellico to "
"slow down significantly. Do you want to save the images separately in "
"Tellico's data directory to improve performance?
Your choice can "
"always be changed in the configuration dialog.
");
KGuiItem yes(i18n("Save Images Separately"));
KGuiItem no(i18n("Save Images in File"));
int res = KMessageBox::warningYesNo(this, msg, QString() /* caption */, yes, no);
if(res == KMessageBox::No) {
Config::setImageLocation(Config::ImagesInAppDir);
}
Config::setAskWriteImagesInFile(false);
}
GUI::CursorSaver cs(Qt::WaitCursor);
if(Data::Document::self()->saveDocument(Data::Document::self()->URL())) {
Kernel::self()->resetHistory();
m_newDocument = false;
updateCaption(false);
m_fileSave->setEnabled(false);
// TODO: call a method of the model instead of the view here
m_detailedView->resetEntryStatus();
} else {
ret = false;
}
}
StatusBar::self()->clearStatus();
return ret;
}
void MainWindow::slotFileSaveAs() {
fileSaveAs();
}
bool MainWindow::fileSaveAs() {
if(!m_editDialog->queryModified()) {
return false;
}
slotStatusMsg(i18n("Saving file with a new filename..."));
QString filter = i18n("Tellico Files") + QLatin1String(" (*.tc *.bc)");
filter += QLatin1String(";;");
filter += i18n("All Files") + QLatin1String(" (*)");
// keyword 'open'
QString fileClass;
const QUrl startUrl = KFileWidget::getStartUrl(QUrl(QStringLiteral("kfiledialog:///open")), fileClass);
const QUrl url = QFileDialog::getSaveFileUrl(this, i18n("Save As"), startUrl, filter);
if(url.isEmpty()) {
StatusBar::self()->clearStatus();
return false;
}
if(url.isLocalFile()) {
KRecentDirs::add(fileClass, url.adjusted(QUrl::RemoveFilename|QUrl::StripTrailingSlash).path());
}
bool ret = true;
if(url.isValid()) {
GUI::CursorSaver cs(Qt::WaitCursor);
m_savingImageLocationChange = true;
// Overwriting an existing file was already confirmed in QFileDialog::getSaveFileUrl()
if(Data::Document::self()->saveDocument(url, true /* force */)) {
Kernel::self()->resetHistory();
KRecentDocument::add(url);
m_fileOpenRecent->addUrl(url);
updateCaption(false);
m_newDocument = false;
m_fileSave->setEnabled(false);
m_detailedView->resetEntryStatus();
} else {
ret = false;
}
m_savingImageLocationChange = false;
}
StatusBar::self()->clearStatus();
return ret;
}
void MainWindow::slotFilePrint() {
slotStatusMsg(i18n("Printing..."));
bool printGrouped = Config::printGrouped();
bool printHeaders = Config::printFieldHeaders();
int imageWidth = Config::maxImageWidth();
int imageHeight = Config::maxImageHeight();
// If the collection is being filtered, warn the user
if(m_detailedView->filter()) {
QString str = i18n("The collection is currently being filtered to show a limited subset of "
"the entries. Only the visible entries will be printed. Continue?");
int ret = KMessageBox::warningContinueCancel(this, str, QString(), KStandardGuiItem::print(),
KStandardGuiItem::cancel(), QStringLiteral("WarnPrintVisible"));
if(ret == KMessageBox::Cancel) {
StatusBar::self()->clearStatus();
return;
}
}
GUI::CursorSaver cs(Qt::WaitCursor);
Export::HTMLExporter exporter(Data::Document::self()->collection());
// only print visible entries
exporter.setEntries(m_detailedView->visibleEntries());
exporter.setXSLTFile(QStringLiteral("tellico-printing.xsl"));
exporter.setPrintHeaders(printHeaders);
exporter.setPrintGrouped(printGrouped);
exporter.setGroupBy(Controller::self()->expandedGroupBy());
if(!printGrouped) { // the sort titles are only used if the entries are not grouped
exporter.setSortTitles(Controller::self()->sortTitles());
}
exporter.setColumns(m_detailedView->visibleColumns());
exporter.setMaxImageSize(imageWidth, imageHeight);
slotStatusMsg(i18n("Processing document..."));
if(Config::printFormatted()) {
exporter.setOptions(Export::ExportUTF8 | Export::ExportFormatted);
} else {
exporter.setOptions(Export::ExportUTF8);
}
QString html = exporter.text();
if(html.isEmpty()) {
XSLTError();
StatusBar::self()->clearStatus();
return;
}
// don't have busy cursor when showing the print dialog
cs.restore();
// myDebug() << html;
slotStatusMsg(i18n("Printing..."));
doPrint(html);
StatusBar::self()->clearStatus();
}
void MainWindow::slotFileQuit() {
slotStatusMsg(i18n("Exiting..."));
close(); // will call queryClose()
StatusBar::self()->clearStatus();
}
void MainWindow::slotEditCut() {
activateEditSlot("cut()");
}
void MainWindow::slotEditCopy() {
activateEditSlot("copy()");
}
void MainWindow::slotEditPaste() {
activateEditSlot("paste()");
}
void MainWindow::activateEditSlot(const char* slot_) {
// the edit widget is the only one that copies, cuts, and pastes
QWidget* w;
if(m_editDialog->isVisible()) {
w = m_editDialog->focusWidget();
} else {
w = qApp->focusWidget();
}
if(w && w->isVisible()) {
const QMetaObject* meta = w->metaObject();
const int idx = meta->indexOfSlot(slot_);
if(idx > -1) {
//myDebug() << "MainWindow invoking" << meta->method(idx).signature();
meta->method(idx).invoke(w, Qt::DirectConnection);
}
}
}
void MainWindow::slotEditSelectAll() {
m_detailedView->selectAllVisible();
}
void MainWindow::slotEditDeselect() {
Controller::self()->slotUpdateSelection(Data::EntryList());
}
void MainWindow::slotToggleEntryEditor() {
if(m_toggleEntryEditor->isChecked()) {
m_editDialog->show();
} else {
m_editDialog->hide();
}
}
void MainWindow::slotShowConfigDialog() {
if(!m_configDlg) {
m_configDlg = new ConfigDialog(this);
connect(m_configDlg, SIGNAL(signalConfigChanged()),
SLOT(slotHandleConfigChange()));
connect(m_configDlg, SIGNAL(finished(int)),
SLOT(slotHideConfigDialog()));
} else {
KWindowSystem::activateWindow(m_configDlg->winId());
}
m_configDlg->show();
}
void MainWindow::slotHideConfigDialog() {
if(m_configDlg) {
m_configDlg->hide();
m_configDlg->deleteLater();
m_configDlg = nullptr;
}
}
void MainWindow::slotShowTipOfDay(bool force_/*=true*/) {
KTipDialog::showTip(this, QStringLiteral("tellico/tellico.tips"), force_);
}
void MainWindow::slotStatusMsg(const QString& text_) {
m_statusBar->setStatus(text_);
}
void MainWindow::slotClearStatus() {
StatusBar::self()->clearStatus();
}
void MainWindow::slotEntryCount() {
Data::CollPtr coll = Data::Document::self()->collection();
if(!coll) {
return;
}
int count = coll->entryCount();
QString text = i18n("Total entries: %1", count);
int selectCount = Controller::self()->selectedEntries().count();
int filterCount = m_detailedView->visibleItems();
// if more than one book is selected, add the number of selected books
if(filterCount < count && selectCount > 1) {
text += QLatin1Char(' ');
text += i18n("(%1 filtered; %2 selected)", filterCount, selectCount);
} else if(filterCount < count) {
text += QLatin1Char(' ');
text += i18n("(%1 filtered)", filterCount);
} else if(selectCount > 1) {
text += QLatin1Char(' ');
text += i18n("(%1 selected)", selectCount);
}
m_statusBar->setCount(text);
}
void MainWindow::slotEnableOpenedActions() {
slotUpdateToolbarIcons();
updateCollectionActions();
// close the filter dialog when a new collection is opened
slotHideFilterDialog();
slotStringMacroDialogFinished();
}
void MainWindow::slotEnableModifiedActions(bool modified_ /*= true*/) {
updateCaption(modified_);
updateCollectionActions();
m_fileSave->setEnabled(modified_);
}
void MainWindow::slotHandleConfigChange() {
const int imageLocation = Config::imageLocation();
const bool autoCapitalize = Config::autoCapitalization();
const bool autoFormat = Config::autoFormat();
const QStringList articles = Config::articleList();
const QStringList nocaps = Config::noCapitalizationList();
const QStringList suffixes = Config::nameSuffixList();
const QStringList prefixes = Config::surnamePrefixList();
m_configDlg->saveConfiguration();
// only modified if there are entries and image location is changed
if(imageLocation != Config::imageLocation() && !Data::Document::self()->isEmpty()) {
slotImageLocationChanged();
}
if(autoCapitalize != Config::autoCapitalization() ||
autoFormat != Config::autoFormat() ||
articles != Config::articleList() ||
nocaps != Config::noCapitalizationList() ||
suffixes != Config::nameSuffixList() ||
prefixes != Config::surnamePrefixList()) {
// invalidate all groups
Data::Document::self()->collection()->invalidateGroups();
// refreshing the title causes the group view to refresh
Controller::self()->slotRefreshField(Data::Document::self()->collection()->fieldByName(QStringLiteral("title")));
}
QString entryXSLTFile = Config::templateName(Kernel::self()->collectionType());
m_entryView->setXSLTFile(entryXSLTFile + QLatin1String(".xsl"));
}
void MainWindow::slotUpdateCollectionToolBar(Tellico::Data::CollPtr coll_) {
if(!coll_) {
myWarning() << "no collection pointer!";
return;
}
QString current = m_groupView->groupBy();
if(current.isEmpty() || !coll_->entryGroups().contains(current)) {
current = coll_->defaultGroupField();
}
const QStringList groups = coll_->entryGroups();
if(groups.isEmpty()) {
m_entryGrouping->clear();
return;
}
QMap