// remove from personal dictionary void AppleSpellChecker::remove(WordLangTuple const & word) { string const word_str = to_utf8(word.word()); AppleSpeller_unlearn(d->speller, word_str.c_str()); LYXERR(Debug::GUI, "unlearn word: \"" << word.word() << "\"") ; advanceChangeNumber(); }
string LyXVC::copy(FileName const & fn) { LYXERR(Debug::LYXVC, "LyXVC: copy"); if (!vcs || fileInVC(fn)) return string(); docstring response; bool ok = Alert::askForText(response, _("LyX VC: Log message"), _("(no log message)")); if (!ok) { LYXERR(Debug::LYXVC, "LyXVC: user cancelled"); return string(); } if (response.empty()) response = _("(no log message)"); string ret = vcs->copy(fn, to_utf8(response)); return ret; }
void PreviewLoader::Impl::finishedGenerating(pid_t pid, int retval) { // Paranoia check! InProgressProcesses::iterator git = in_progress_.find(pid); if (git == in_progress_.end()) { lyxerr << "PreviewLoader::finishedGenerating(): unable to find " "data for PID " << pid << endl; return; } string const command = git->second.command; string const status = retval > 0 ? "failed" : "succeeded"; LYXERR(Debug::GRAPHICS, "PreviewLoader::finishedInProgress(" << retval << "): processing " << status << " for " << command); if (retval > 0) return; // Read the metrics file, if it exists vector<double> ascent_fractions(git->second.snippets.size()); setAscentFractions(ascent_fractions, git->second.metrics_file); // Add these newly generated bitmap files to the cache and // start loading them into LyX. BitmapFile::const_iterator it = git->second.snippets.begin(); BitmapFile::const_iterator end = git->second.snippets.end(); list<PreviewImagePtr> newimages; int metrics_counter = 0; for (; it != end; ++it, ++metrics_counter) { string const & snip = it->first; FileName const & file = it->second; double af = ascent_fractions[metrics_counter]; // Add the image to the cache only if it's actually present if (file.isReadableFile()) { PreviewImagePtr ptr(new PreviewImage(parent_, snip, file, af)); cache_[snip] = ptr; newimages.push_back(ptr); } } // Remove the item from the list of still-executing processes. in_progress_.erase(git); // Tell the outside world list<PreviewImagePtr>::const_reverse_iterator nit = newimages.rbegin(); list<PreviewImagePtr>::const_reverse_iterator nend = newimages.rend(); for (; nit != nend; ++nit) { imageReady(*nit->get()); } }
LyXDataSocket::~LyXDataSocket() { if (::close(fd_) != 0) lyxerr << "lyx: Data socket " << fd_ << " IO error on closing: " << strerror(errno); theApp()->unregisterSocketCallback(fd_); LYXERR(Debug::LYXSERVER, "lyx: Data socket " << fd_ << " quitting."); }
enchant::Dict * EnchantChecker::Private::addSpeller(string const & lang) { Speller m; try { LYXERR(Debug::FILES, "request enchant speller for language " << lang); m.speller = broker().request_dict(lang); } catch (enchant::Exception & e) { // FIXME error handling? const char * what = e.what(); LYXERR(Debug::FILES, "cannot add enchant speller: " << ((what && *what) ? what : "unspecified enchant exception in request_dict()")); m.speller = 0; } spellers_[lang] = m; return m.speller; }
docstring const GuiSelection::get() const { QString const str = qApp->clipboard()->text(QClipboard::Selection) .normalized(QString::NormalizationForm_C); LYXERR(Debug::SELECTION, "GuiSelection::get: " << str); if (str.isNull()) return docstring(); return internalLineEnding(str); }
void GuiClipboard::on_dataChanged() { //Note: we do not really need to run cache_.update() unless the //data has been changed *and* the GuiClipboard has been queried. //However if run cache_.update() the moment a process grabs the //clipboard, the process holding the clipboard presumably won't //yet be frozen, and so we won't need to wait 5 seconds for Qt //to time-out waiting for the clipboard. cache_.update(); QStringList l = cache_.formats(); LYXERR(Debug::ACTION, "Qt Clipboard changed. We found the following mime types:"); for (int i = 0; i < l.count(); i++) LYXERR(Debug::ACTION, l.value(i)); plaintext_clipboard_empty_ = qApp->clipboard()-> text(QClipboard::Clipboard).isEmpty(); has_text_contents_ = hasTextContents(); has_graphics_contents_ = hasGraphicsContents(); }
string LyXVC::checkOut() { if (!vcs) return string(); //RCS allows checkOut only in ReadOnly mode if (vcs->toggleReadOnlyEnabled() && !owner_->hasReadonlyFlag()) return string(); LYXERR(Debug::LYXVC, "LyXVC: checkOut"); return vcs->checkOut(); }
void CacheMimeData::update() { time_t const start_time = current_time(); LYXERR(Debug::ACTION, "Creating CacheMimeData object"); cached_formats_ = read_clipboard()->formats(); // Qt times out after 5 seconds if it does not recieve a response. if (current_time() - start_time > 3) { LYXERR0("No timely response from clipboard, perhaps process " << "holding clipboard is frozen?"); } }
LyXVC::CommandResult LyXVC::checkIn(string & log) { LYXERR(Debug::LYXVC, "LyXVC: checkIn"); if (!vcs) return ErrorBefore; docstring empty(_("(no log message)")); docstring response; bool ok = true; if (vcs->isCheckInWithConfirmation()) ok = Alert::askForText(response, _("LyX VC: Log Message")); if (ok) { if (response.empty()) response = empty; //shell collisions response = subst(response, from_ascii("\""), from_ascii("\\\"")); return vcs->checkIn(to_utf8(response), log); } else { LYXERR(Debug::LYXVC, "LyXVC: user cancelled"); return Cancelled; } }
// Close the socket and remove the address of the filesystem. ServerSocket::~ServerSocket() { if (fd_ != -1) { BOOST_ASSERT (theApp()); // theApp()->unregisterSocketCallback(fd_); if (::close(fd_) != 0) lyxerr << "lyx: Server socket " << fd_ << " IO error on closing: " << strerror(errno) << endl; } address_.removeFile(); LYXERR(Debug::LYXSERVER, "lyx: Server socket quitting"); }
void PreviewLoader::Impl::add(string const & latex_snippet) { if (!pconverter_ || status(latex_snippet) != NotFound) return; string const snippet = trim(latex_snippet); if (snippet.empty()) return; LYXERR(Debug::GRAPHICS, "adding snippet:\n" << snippet); pending_.push_back(snippet); }
docstring const GuiClipboard::getAsText(TextType type) const { // text data from other applications if ((type == AnyTextType || type == LyXOrPlainTextType) && hasTextContents(LyXTextType)) type = LyXTextType; if (type == AnyTextType && hasTextContents(LaTeXTextType)) type = LaTeXTextType; if (type == AnyTextType && hasTextContents(HtmlTextType)) type = HtmlTextType; QString str; switch (type) { case LyXTextType: // must not convert to docstring, since file can contain // mixed encodings (use getAsLyX() instead) break; case AnyTextType: case LyXOrPlainTextType: case PlainTextType: str = qApp->clipboard()->text(QClipboard::Clipboard) .normalized(QString::NormalizationForm_C); break; case LaTeXTextType: { QMimeData const * source = qApp->clipboard()->mimeData(QClipboard::Clipboard); if (source) { // First try LaTeX, then TeX (we do not distinguish // for clipboard purposes) if (source->hasFormat(latexMimeType())) { str = source->data(latexMimeType()); str = str.normalized(QString::NormalizationForm_C); } else if (source->hasFormat(texMimeType())) { str = source->data(texMimeType()); str = str.normalized(QString::NormalizationForm_C); } } break; } case HtmlTextType: { QString subtype = "html"; str = qApp->clipboard()->text(subtype, QClipboard::Clipboard) .normalized(QString::NormalizationForm_C); str = tidyHtml(str); break; } } LYXERR(Debug::ACTION, "GuiClipboard::getAsText(" << type << "): `" << str << "'"); if (str.isNull()) return docstring(); return internalLineEnding(str); }
// Address is the unix address for the socket. // MAX_CLIENTS is the maximum number of clients // that can connect at the same time. ServerSocket::ServerSocket(FileName const & addr) : fd_(socktools::listen(addr, 3)), address_(addr) { if (fd_ == -1) { LYXERR(Debug::LYXSERVER, "lyx: Disabling LyX socket."); return; } // These env vars are used by DVI inverse search // Needed by xdvi setEnv("XEDITOR", "lyxclient -g %f %l"); // Needed by lyxclient setEnv("LYXSOCKET", address_.absFileName()); theApp()->registerSocketCallback( fd_, bind(&ServerSocket::serverCallback, this) ); LYXERR(Debug::LYXSERVER, "lyx: New server socket " << fd_ << ' ' << address_.absFileName()); }
SpellChecker::Result AppleSpellChecker::check(WordLangTuple const & word) { if (!hasDictionary(word.lang())) return WORD_OK; string const word_str = to_utf8(word.word()); string const lang = d->languageMap[word.lang()->lang()]; SpellCheckResult result = AppleSpeller_check(d->speller, word_str.c_str(), lang.c_str()); LYXERR(Debug::GUI, "spellCheck: \"" << word.word() << "\" = " << d->toString(result) << ", lang = " << lang) ; return d->toResult(result); }
static QMimeData const * read_clipboard() { LYXERR(Debug::ACTION, "Getting Clipboard"); QMimeData const * source = qApp->clipboard()->mimeData(QClipboard::Clipboard); if (!source) { LYXERR0("0 bytes (no QMimeData)"); return new QMimeData; } // It appears that doing IO between getting a mimeData object // and using it can cause a crash (maybe Qt used IO // as an excuse to free() it? Anyway let's not introduce // any new IO here, so e.g. leave the following line commented. // lyxerr << "Got Clipboard (" << (long) source << ")\n" ; return source; }
bool LyXVC::registrer() { FileName const filename = owner_->fileName(); // there must be a file to save if (!filename.isReadableFile()) { Alert::error(_("Document not saved"), _("You must save the document " "before it can be registered.")); return false; } // it is very likely here that the vcs is not created yet... if (!vcs) { //check in the root directory of the document FileName const cvs_entries(onlyPath(filename.absFileName()) + "/CVS/Entries"); FileName const svn_entries(onlyPath(filename.absFileName()) + "/.svn/entries"); FileName const git_index(onlyPath(filename.absFileName()) + "/.git/index"); if (git_index.isReadableFile()) { LYXERR(Debug::LYXVC, "LyXVC: registering " << to_utf8(filename.displayName()) << " with GIT"); vcs.reset(new GIT(git_index, owner_)); } else if (svn_entries.isReadableFile()) { LYXERR(Debug::LYXVC, "LyXVC: registering " << to_utf8(filename.displayName()) << " with SVN"); vcs.reset(new SVN(svn_entries, owner_)); } else if (cvs_entries.isReadableFile()) { LYXERR(Debug::LYXVC, "LyXVC: registering " << to_utf8(filename.displayName()) << " with CVS"); vcs.reset(new CVS(cvs_entries, owner_)); } else { LYXERR(Debug::LYXVC, "LyXVC: registering " << to_utf8(filename.displayName()) << " with RCS"); vcs.reset(new RCS(FileName(), owner_)); } } LYXERR(Debug::LYXVC, "LyXVC: registrer"); docstring response; bool ok = Alert::askForText(response, _("LyX VC: Initial description"), _("(no initial description)")); if (!ok) { LYXERR(Debug::LYXVC, "LyXVC: user cancelled"); vcs.reset(0); return false; } if (response.empty()) response = _("(no initial description)"); vcs->registrer(to_utf8(response)); return true; }
void LoaderQueue::loadNext() { LYXERR(Debug::GRAPHICS, "LoaderQueue: " << cache_queue_.size() << " items in the queue"); int counter = s_numimages_; while (!cache_queue_.empty() && counter--) { Cache::ItemPtr ptr = cache_queue_.front(); cache_set_.erase(ptr); cache_queue_.pop_front(); if (ptr->status() == WaitingToLoad) ptr->startLoading(); } if (!cache_queue_.empty()) startLoader(); else stopLoader(); }
bool GuiSelection::empty() const { if (!selection_supported_) return true; // Cache which is to speed up selection-status read // (4 calls when open Edit menu). static bool text_selection_empty; if (schedule_check_) { text_selection_empty = qApp->clipboard()-> text(QClipboard::Selection).isEmpty(); schedule_check_ = false; } LYXERR(Debug::SELECTION, "GuiSelection::filled: " << !text_selection_empty); return text_selection_empty; }
bool LyXVC::revert() { LYXERR(Debug::LYXVC, "LyXVC: revert"); if (!vcs) return false; docstring const file = owner_->fileName().displayName(20); docstring text = bformat(_("Reverting to the stored version of the " "document %1$s will lose all current changes.\n\n" "Do you want to revert to the older version?"), file); int ret = 0; if (vcs->isRevertWithConfirmation()) ret = Alert::prompt(_("Revert to stored version of document?"), text, 0, 1, _("&Revert"), _("&Cancel")); return ret == 0 && vcs->revert(); }
FontLoader::FontLoader() { QString const fonts_dir = toqstr(addPath(package().system_support().absFileName(), "fonts")); for (int i = 0 ; i < num_math_fonts; ++i) { QString const font_file = fonts_dir + '/' + math_fonts[i] + ".ttf"; int fontID = QFontDatabase::addApplicationFont(font_file); LYXERR(Debug::FONT, "Adding font " << font_file << (fontID < 0 ? " FAIL" : " OK")); } for (int i1 = 0; i1 < NUM_FAMILIES; ++i1) for (int i2 = 0; i2 < NUM_SERIES; ++i2) for (int i3 = 0; i3 < NUM_SHAPE; ++i3) for (int i4 = 0; i4 < NUM_SIZE; ++i4) fontinfo_[i1][i2][i3][i4] = 0; }
bool AppleSpellChecker::hasDictionary(Language const * lang) const { string const langmap = d->languageMap[lang->lang()]; bool result = !langmap.empty(); if (result) return result; result = AppleSpeller_hasLanguage(d->speller,lang->code().c_str()); if (result) { d->languageMap[lang->lang()] = lang->code(); } else { result = AppleSpeller_hasLanguage(d->speller,lang->lang().c_str()); if (result) d->languageMap[lang->lang()] = lang->lang(); } LYXERR(Debug::GUI, "has dictionary: " << lang->lang() << " = " << result) ; return result; }
int writeExternal(InsetExternalParams const & params, string const & format, Buffer const & buffer, odocstream & os, ExportData & exportdata, bool external_in_tmpdir, bool dryrun) { Template const * const et_ptr = getTemplatePtr(params); if (!et_ptr) return 0; Template const & et = *et_ptr; Template::Formats::const_iterator cit = et.formats.find(format); if (cit == et.formats.end()) { LYXERR(Debug::EXTERNAL, "External template format '" << format << "' not specified in template " << params.templatename()); return 0; } if (!dryrun || contains(cit->second.product, "$$Contents")) updateExternal(params, format, buffer, exportdata, external_in_tmpdir, dryrun); bool const use_latex_path = format == "LaTeX"; string str = doSubstitution(params, buffer, cit->second.product, use_latex_path, external_in_tmpdir); string const absname = makeAbsPath( params.filename.outputFileName(buffer.filePath()), buffer.filePath()).absFileName(); if (!external_in_tmpdir && !isValidLaTeXFileName(absname)) { lyx::frontend::Alert::warning(_("Invalid filename"), _("The following filename is likely to cause trouble " "when running the exported file through LaTeX: ") + from_utf8(absname)); } str = substituteCommands(params, str, format); str = substituteOptions(params, str, format); // FIXME UNICODE os << from_utf8(str); return int(count(str.begin(), str.end(),'\n')); }
time_t from_asctime_utc(string t) { // Example for the format: "Sun Nov 6 10:39:39 2011\n" // Generously remove trailing '\n' (and other whitespace if needed) t = trim(t, " \t\r\n"); // toDateTime() is too stupid to recognize variable amounts of // whitespace (needed because ctime() outputs double spaces before // single digit day numbers and hours) t = subst(t, " ", " "); QString const format("ddd MMM d H:mm:ss yyyy"); QLocale loc("C"); QDateTime loc_dt = loc.toDateTime(toqstr(t), format); if (!loc_dt.isValid()) { LYXERR(Debug::LOCALE, "Could not parse `" << t << "´ (invalid format)"); return static_cast<time_t>(-1); } loc_dt.setTimeSpec(Qt::UTC); return loc_dt.toTime_t(); }
// Creates a new LyXDataSocket and checks to see if the connection // is OK and if the number of clients does not exceed MAX_CLIENTS void ServerSocket::serverCallback() { int const client_fd = socktools::accept(fd_); if (fd_ == -1) { LYXERR(Debug::LYXSERVER, "lyx: Failed to accept new client"); return; } if (clients.size() >= MAX_CLIENTS) { writeln("BYE:Too many clients connected"); return; } // Register the new client. clients[client_fd] = shared_ptr<LyXDataSocket>(new LyXDataSocket(client_fd)); theApp()->registerSocketCallback( client_fd, bind(&ServerSocket::dataCallback, this, client_fd) ); }
void GuiSelection::on_dataChanged() { schedule_check_ = true; LYXERR(Debug::SELECTION, "GuiSelection::on_dataChanged"); }
Inset * Inset::editXY(Cursor &, int x, int y) { LYXERR(Debug::INSETS, "x: " << x << " y: " << y); return this; }
void Font::validate(LaTeXFeatures & features) const { BufferParams const & bparams = features.bufferParams(); Language const * doc_language = bparams.language; if (bits_.noun() == FONT_ON) { LYXERR(Debug::LATEX, "font.noun: " << bits_.noun()); features.require("noun"); LYXERR(Debug::LATEX, "Noun enabled. Font: " << to_utf8(stateText(0))); } if (bits_.underbar() == FONT_ON) { LYXERR(Debug::LATEX, "font.underline: " << bits_.underbar()); features.require("ulem"); LYXERR(Debug::LATEX, "Underline enabled. Font: " << to_utf8(stateText(0))); } if (bits_.strikeout() == FONT_ON) { LYXERR(Debug::LATEX, "font.strikeout: " << bits_.strikeout()); features.require("ulem"); LYXERR(Debug::LATEX, "Strikeout enabled. Font: " << to_utf8(stateText(0))); } if (bits_.uuline() == FONT_ON) { LYXERR(Debug::LATEX, "font.uuline: " << bits_.uuline()); features.require("ulem"); LYXERR(Debug::LATEX, "Double underline enabled. Font: " << to_utf8(stateText(0))); } if (bits_.uwave() == FONT_ON) { LYXERR(Debug::LATEX, "font.uwave: " << bits_.uwave()); features.require("ulem"); LYXERR(Debug::LATEX, "Wavy underline enabled. Font: " << to_utf8(stateText(0))); } switch (bits_.color()) { case Color_none: case Color_inherit: case Color_ignore: // probably we should put here all interface colors used for // font displaying! For now I just add this ones I know of (Jug) case Color_latex: case Color_notelabel: break; default: features.require("color"); LYXERR(Debug::LATEX, "Color enabled. Font: " << to_utf8(stateText(0))); } // FIXME: Do something for background and soul package? if (((features.usePolyglossia() && lang_->polyglossia() != doc_language->polyglossia()) || (features.useBabel() && lang_->babel() != doc_language->babel()) || (doc_language->encoding()->package() == Encoding::CJK && lang_ != doc_language)) && lang_ != ignore_language && lang_ != latex_language) { features.useLanguage(lang_); LYXERR(Debug::LATEX, "Found language " << lang_->lang()); } }
void writePlaintextParagraph(Buffer const & buf, Paragraph const & par, odocstream & os, OutputParams const & runparams, bool & ref_printed) { int ltype = 0; depth_type ltype_depth = 0; depth_type depth = par.params().depth(); // First write the layout string const tmp = to_utf8(par.layout().name()); if (compare_ascii_no_case(tmp, "itemize") == 0) { ltype = 1; ltype_depth = depth + 1; } else if (compare_ascii_no_case(tmp, "enumerate") == 0) { ltype = 2; ltype_depth = depth + 1; } else if (contains(ascii_lowercase(tmp), "ection")) { ltype = 3; ltype_depth = depth + 1; } else if (contains(ascii_lowercase(tmp), "aragraph")) { ltype = 4; ltype_depth = depth + 1; } else if (compare_ascii_no_case(tmp, "description") == 0) { ltype = 5; ltype_depth = depth + 1; } else if (compare_ascii_no_case(tmp, "abstract") == 0) { ltype = 6; ltype_depth = 0; } else if (compare_ascii_no_case(tmp, "bibliography") == 0) { ltype = 7; ltype_depth = 0; } else { ltype = 0; ltype_depth = 0; } /* the labelwidthstring used in lists */ /* noindent ? */ /* what about the alignment */ // runparams.linelen == 0 is special and means we don't have paragraph breaks string::size_type currlinelen = 0; os << docstring(depth * 2, ' '); currlinelen += depth * 2; //-- // we should probably change to the paragraph language in the // support/gettext.here (if possible) so that strings are output in // the correct language! (20012712 Jug) //-- switch (ltype) { case 0: // Standard case 4: // (Sub)Paragraph case 5: // Description break; case 6: // Abstract if (runparams.linelen > 0) { os << buf.B_("Abstract") << "\n\n"; currlinelen = 0; } else { docstring const abst = buf.B_("Abstract: "); os << abst; currlinelen += abst.length(); } break; case 7: // Bibliography if (!ref_printed) { if (runparams.linelen > 0) { os << buf.B_("References") << "\n\n"; currlinelen = 0; } else { docstring const refs = buf.B_("References: "); os << refs; currlinelen += refs.length(); } ref_printed = true; } break; default: { docstring const label = par.params().labelString(); if (!label.empty()) { os << label << ' '; currlinelen += label.length() + 1; } break; } } if (currlinelen == 0) { pair<int, docstring> p = addDepth(depth, ltype_depth); os << p.second; currlinelen += p.first; } docstring word; for (pos_type i = 0; i < par.size(); ++i) { // deleted characters don't make much sense in plain text output if (par.isDeleted(i)) continue; char_type c = par.getUChar(buf.params(), i); if (par.isInset(i) || c == ' ') { if (runparams.linelen > 0 && currlinelen + word.length() > runparams.linelen) { os << '\n'; pair<int, docstring> p = addDepth(depth, ltype_depth); os << p.second; currlinelen = p.first; } os << word; currlinelen += word.length(); word.erase(); } if (par.isInset(i)) { OutputParams rp = runparams; rp.depth = par.params().depth(); int len = par.getInset(i)->plaintext(os, rp); if (len >= Inset::PLAINTEXT_NEWLINE) currlinelen = len - Inset::PLAINTEXT_NEWLINE; else currlinelen += len; continue; } switch (c) { case ' ': os << ' '; currlinelen++; break; case '\0': LYXERR(Debug::INFO, "writePlaintextFile: NUL char in structure."); break; default: word += c; break; } } // currlinelen may be greater than runparams.linelen! // => check whether word is empty and do nothing in this case if (!word.empty()) { if (runparams.linelen > 0 && currlinelen + word.length() > runparams.linelen) { os << '\n'; pair<int, docstring> p = addDepth(depth, ltype_depth); os << p.second; currlinelen = p.first; } os << word; } }
void LoaderQueue::stopLoader() { timer.stop(); running_ = false ; LYXERR(Debug::GRAPHICS, "LoaderQueue: I'm going to sleep"); }