Example #1
0
TextClass::ReturnValues TextClass::readWithoutConv(FileName const & filename, ReadType rt)
{
	if (!filename.isReadableFile()) {
		lyxerr << "Cannot read layout file `" << filename << "'."
		       << endl;
		return ERROR;
	}

	LYXERR(Debug::TCLASS, "Reading " + translateReadType(rt) + ": " +
		to_utf8(makeDisplayPath(filename.absFileName())));

	// Define the plain layout used in table cells, ert, etc. Note that 
	// we do this before loading any layout file, so that classes can 
	// override features of this layout if they should choose to do so.
	if (rt == BASECLASS && !hasLayout(plain_layout_))
		layoutlist_.push_back(createBasicLayout(plain_layout_));

	Lexer lexrc(textClassTags);
	lexrc.setFile(filename);
	ReturnValues retval = read(lexrc, rt);
	
	LYXERR(Debug::TCLASS, "Finished reading " + translateReadType(rt) + ": " +
			to_utf8(makeDisplayPath(filename.absFileName())));

	return retval;
}
Example #2
0
FileName GuiClipboard::getAsGraphics(Cursor const & cur, GraphicsType type) const
{
	// get the filename from the user
	FileName filename = getPastedGraphicsFileName(cur, type);
	if (filename.empty())
		return FileName();

	// handle image cases first
	if (type == PngGraphicsType || type == JpegGraphicsType) {
		// get image from QImage from clipboard
		QImage image = qApp->clipboard()->image();
		if (image.isNull()) {
			LYXERR(Debug::ACTION, "No image in clipboard");
			return FileName();
		}

		// convert into graphics format
		QByteArray ar;
		QBuffer buffer(&ar);
		buffer.open(QIODevice::WriteOnly);
		if (type == PngGraphicsType)
			image.save(toqstr(filename.absFileName()), "PNG");
		else if (type == JpegGraphicsType)
			image.save(toqstr(filename.absFileName()), "JPEG");
		else
			LASSERT(false, /**/);
		
		return filename;
	}
Example #3
0
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;
}
Example #4
0
bool FileName::clonePermissions(FileName const & source)
{
	QFile fin(toqstr(source.absFileName()));
	QFile f(toqstr(absFileName()));

	return f.setPermissions(fin.permissions());
}
Example #5
0
void CacheItem::Impl::convertToDisplayFormat()
{
	LYXERR(Debug::GRAPHICS, "\tConverting it to " << to_ << " format.");

	// Make a local copy in case we unzip it
	FileName filename;
	string from;
	if (!tryDisplayFormat(filename, from)) {
		// The image status has changed, tell it to the outside world.
		statusChanged();
		return;
	}

	// We will need a conversion, tell it to the outside world.
	setStatus(Converting);

	// Add some stuff to create a uniquely named temporary file.
	// This file is deleted in loadImage after it is loaded into memory.
	FileName const to_file_base = FileName::tempName("CacheItem");
	remove_loaded_file_ = true;

	// Connect a signal to this->imageConverted and pass this signal to
	// the graphics converter so that we can load the modified file
	// on completion of the conversion process.
	converter_.reset(new Converter(filename, to_file_base.absFileName(), from, to_));
	converter_->connect(bind(&Impl::imageConverted, this, _1));
	converter_->startConversion();
}
Example #6
0
bool LyXVC::file_not_found_hook(FileName const & fn)
{
	// Check if file is under RCS.
	// This happens if we are trying to load non existent
	// file on disk, but existent in ,v version.
	bool foundRCS = !RCS::findFile(fn).empty();
	bool foundCVS = foundRCS ? false : !CVS::findFile(fn).empty();
	bool foundSVN = (foundRCS || foundCVS) ? false : !SVN::findFile(fn).empty();
	bool foundGIT = (foundRCS || foundCVS || foundSVN) ? false : !GIT::findFile(fn).empty();
	if (foundRCS || foundCVS || foundSVN || foundGIT) {
		docstring const file = makeDisplayPath(fn.absFileName(), 20);
		docstring const text =
			bformat(_("Do you want to retrieve the document"
						   " %1$s from version control?"), file);
		int const ret = Alert::prompt(_("Retrieve from version control?"),
			text, 0, 1, _("&Retrieve"), _("&Cancel"));

		if (ret == 0) {
			// Since the retrieve commands are implemented using
			// more general update commands we need to ensure that
			// we do not change an existing file by accident.
			if (fn.exists())
				return false;
			if (foundRCS)
				return RCS::retrieve(fn);
			else if (foundCVS)
				return CVS::retrieve(fn);
			else if (foundSVN)
				return SVN::retrieve(fn);
			else
				return GIT::retrieve(fn);
		}
	}
	return false;
}
Example #7
0
FileName const RCS::findFile(FileName const & file)
{
	// Check if *,v exists.
	FileName tmp(file.absFileName() + ",v");
	LYXERR(Debug::LYXVC, "LyXVC: Checking if file is under rcs: " << tmp);
	if (tmp.isReadableFile()) {
		LYXERR(Debug::LYXVC, "Yes, " << file << " is under rcs.");
		return tmp;
	}

	// Check if RCS/*,v exists.
	tmp = FileName(addName(addPath(onlyPath(file.absFileName()), "RCS"), file.absFileName()) + ",v");
	LYXERR(Debug::LYXVC, "LyXVC: Checking if file is under rcs: " << tmp);
	if (tmp.isReadableFile()) {
		LYXERR(Debug::LYXVC, "Yes, " << file << " is under rcs.");
		return tmp;
	}

	return FileName();
}
Example #8
0
/** copy file \p sourceFile to \p destFile. If \p force is false, the user
 *  will be asked before existing files are overwritten. If \p only_tmp
 *  is true, then only copy files that are in our tmp dir (to avoid other files
 *  overwriting themselves).
 *  \return
 *  - SUCCESS if this file got copied
 *  - FORCE   if subsequent calls should not ask for confirmation before
 *            overwriting files anymore.
 *  - CANCEL  if the export should be cancelled
 */
CopyStatus copyFile(string const & format,
		    FileName const & sourceFile, FileName const & destFile,
		    string const & latexFile, bool force, bool only_tmp)
{
	CopyStatus ret = force ? FORCE : SUCCESS;

	// This check could be changed to
	// boost::filesystem::equivalent(sourceFile, destFile) if export to
	// other directories than the document directory is desired.
	// Also don't overwrite files that already exist and are identical
	// to the source files.
	if ((only_tmp && !prefixIs(onlyPath(sourceFile.absFileName()), package().temp_dir().absFileName()))
	    || sourceFile.checksum() == destFile.checksum())
		return ret;

	if (!force) {
		switch(checkOverwrite(destFile)) {
		case 0:
			return SUCCESS;
		case 1:
			ret = SUCCESS;
			break;
		case 2:
			ret = FORCE;
			break;
		default:
			return CANCEL;
		}
	}

	Mover const & mover = getMover(format);
	if (!mover.copy(sourceFile, destFile, latexFile))
		Alert::error(_("Couldn't copy file"),
			     bformat(_("Copying %1$s to %2$s failed."),
				     makeDisplayPath(sourceFile.absFileName()),
				     makeDisplayPath(destFile.absFileName())));

	return ret;
}
Example #9
0
/// Ask the user what to do if a file already exists
static int checkOverwrite(FileName const & filename)
{
	if (!filename.exists())
		return 1;

	docstring text = bformat(_("The file %1$s already exists.\n\n"
				   "Do you want to overwrite that file?"),
				   makeDisplayPath(filename.absFileName()));
	return Alert::prompt(_("Overwrite file?"),
				text, 0, 3,
				_("&Keep file"), _("&Overwrite"),
				_("Overwrite &all"), _("&Cancel export"));
}
Example #10
0
bool ConverterCache::copy(FileName const & orig_from, string const & to_format,
		FileName const & dest) const
{
	if (!lyxrc.use_converter_cache || orig_from.empty() || dest.empty())
		return false;
	LYXERR(Debug::FILES, orig_from << ' ' << to_format << ' ' << dest);

	// FIXME: Should not hardcode this (see bug 3819 for details)
	if (to_format == "pstex") {
		FileName const dest_eps(changeExtension(dest.absFileName(), "eps"));
		if (!copy(orig_from, "eps", dest_eps))
			return false;
	} else if (to_format == "pdftex") {
		FileName const dest_pdf(changeExtension(dest.absFileName(), "pdf"));
		if (!copy(orig_from, "pdf", dest_pdf))
			return false;
	}

	CacheItem * const item = pimpl_->find(orig_from, to_format);
	LASSERT(item, /**/);
	Mover const & mover = getMover(to_format);
	return mover.copy(item->cache_name, dest,
	                  onlyFileName(dest.absFileName()));
}
Example #11
0
void rescanTexStyles(string const & arg)
{
	// Run rescan in user lyx directory
	PathChanger p(package().user_support());
	FileName const prog = support::libFileSearch("scripts", "TeXFiles.py");
	Systemcall one;
	string const command = os::python() + ' ' +
	    quoteName(prog.toFilesystemEncoding()) + ' ' +
	    arg;
	int const status = one.startscript(Systemcall::Wait, command);
	if (status == 0)
		return;
	// FIXME UNICODE
	frontend::Alert::error(_("Could not update TeX information"),
		bformat(_("The script `%1$s' failed."), from_utf8(prog.absFileName())));
}
Example #12
0
string const LyXVC::getLogFile() const
{
	if (!vcs)
		return string();

	TempFile tempfile("lyxvclog");
	tempfile.setAutoRemove(false);
	FileName const tmpf = tempfile.name();
	if (tmpf.empty()) {
		LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf);
		return string();
	}
	LYXERR(Debug::LYXVC, "Generating logfile " << tmpf);
	vcs->getLog(tmpf);
	return tmpf.absFileName();
}
Example #13
0
/// Connect to the socket \p name.
int connect(FileName const & name)
{
	int fd; // File descriptor for the socket
	sockaddr_un addr; // Structure that hold the socket address

	string const encoded = name.toFilesystemEncoding();
	// char sun_path[108]
	string::size_type len = encoded.size();
	if (len > 107) {
		cerr << "lyxclient: Socket address '" << name
		     << "' too long." << endl;
		return -1;
	}
	// Synonims for AF_UNIX are AF_LOCAL and AF_FILE
	addr.sun_family = AF_UNIX;
	encoded.copy(addr.sun_path, 107);
	addr.sun_path[len] = '\0';

	if ((fd = ::socket(PF_UNIX, SOCK_STREAM, 0))== -1) {
		cerr << "lyxclient: Could not create socket descriptor: "
		     << strerror(errno) << endl;
		return -1;
	}
	if (::connect(fd,
		      reinterpret_cast<struct sockaddr *>(&addr),
		      sizeof(addr)) == -1) {
		cerr << "lyxclient: Could not connect to socket " << name.absFileName()
		     << ": " << strerror(errno) << endl;
		::close(fd);
		return -1;
	}
	if (::fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
		cerr << "lyxclient: Could not set O_NONBLOCK for socket: "
		     << strerror(errno) << endl;
		::close(fd);
		return -1;
	}
	return fd;
}
Example #14
0
// Reads a textclass structure from file.
TextClass::ReturnValues TextClass::read(Lexer & lexrc, ReadType rt) 
{
	if (!lexrc.isOK())
		return ERROR;

	// Format of files before the 'Format' tag was introduced
	int format = 1;
	bool error = false;

	// parsing
	while (lexrc.isOK() && !error) {
		int le = lexrc.lex();

		switch (le) {
		case Lexer::LEX_FEOF:
			continue;

		case Lexer::LEX_UNDEF:
			lexrc.printError("Unknown TextClass tag `$$Token'");
			error = true;
			continue;

		default:
			break;
		}

		// used below to track whether we are in an IfStyle or IfCounter tag.
		bool ifstyle    = false;
		bool ifcounter  = false;

		switch (static_cast<TextClassTags>(le)) {

		case TC_FORMAT:
			if (lexrc.next())
				format = lexrc.getInteger();
			break;

		case TC_OUTPUTFORMAT:
			if (lexrc.next())
				outputFormat_ = lexrc.getString();
			break;

		case TC_OUTPUTTYPE:
			readOutputType(lexrc);
			switch(outputType_) {
			case LATEX:
				outputFormat_ = "latex";
				break;
			case DOCBOOK:
				outputFormat_ = "docbook";
				break;
			case LITERATE:
				outputFormat_ = "literate";
				break;
			}
			break;

		case TC_INPUT: // Include file
			if (lexrc.next()) {
				string const inc = lexrc.getString();
				FileName tmp = libFileSearch("layouts", inc,
							    "layout");

				if (tmp.empty()) {
					lexrc.printError("Could not find input file: " + inc);
					error = true;
				} else if (!read(tmp, MERGE)) {
					lexrc.printError("Error reading input file: " + tmp.absFileName());
					error = true;
				}
			}
			break;

		case TC_DEFAULTSTYLE:
			if (lexrc.next()) {
				docstring const name = from_utf8(subst(lexrc.getString(),
							  '_', ' '));
				defaultlayout_ = name;
			}
			break;

		case TC_IFSTYLE:
			ifstyle = true;
			// fall through
		case TC_STYLE: {
			if (!lexrc.next()) {
				lexrc.printError("No name given for style: `$$Token'.");
				error = true;
				break;
			}
			docstring const name = from_utf8(subst(lexrc.getString(),
							'_', ' '));
			if (name.empty()) {
				string s = "Could not read name for style: `$$Token' "
					+ lexrc.getString() + " is probably not valid UTF-8!";
				lexrc.printError(s);
				Layout lay;
				// Since we couldn't read the name, we just scan the rest
				// of the style and discard it.
				error = !readStyle(lexrc, lay);
			} else if (hasLayout(name)) {
				Layout & lay = operator[](name);
				error = !readStyle(lexrc, lay);
			} else if (!ifstyle) {
				Layout layout;
				layout.setName(name);
				error = !readStyle(lexrc, layout);
				if (!error)
					layoutlist_.push_back(layout);

				if (defaultlayout_.empty()) {
					// We do not have a default layout yet, so we choose
					// the first layout we encounter.
					defaultlayout_ = name;
				}
			}
			else {
				// this was an ifstyle where we didn't have the style
				// scan the rest and discard it
				Layout lay;
				readStyle(lexrc, lay);
			}

			// reset flag
			ifstyle = false;
			break;
		}

		case TC_NOSTYLE:
			if (lexrc.next()) {
				docstring const style = from_utf8(subst(lexrc.getString(),
						     '_', ' '));
				if (!deleteLayout(style))
					lyxerr << "Cannot delete style `"
					       << to_utf8(style) << '\'' << endl;
			}
			break;

		case TC_COLUMNS:
			if (lexrc.next())
				columns_ = lexrc.getInteger();
			break;

		case TC_SIDES:
			if (lexrc.next()) {
				switch (lexrc.getInteger()) {
				case 1: sides_ = OneSide; break;
				case 2: sides_ = TwoSides; break;
				default:
					lyxerr << "Impossible number of page"
						" sides, setting to one."
					       << endl;
					sides_ = OneSide;
					break;
				}
			}
			break;

		case TC_PAGESTYLE:
			lexrc.next();
			pagestyle_ = rtrim(lexrc.getString());
			break;

		case TC_DEFAULTFONT:
			defaultfont_ = lyxRead(lexrc);
			if (!defaultfont_.resolved()) {
				lexrc.printError("Warning: defaultfont should "
						 "be fully instantiated!");
				defaultfont_.realize(sane_font);
			}
			break;

		case TC_SECNUMDEPTH:
			lexrc.next();
			secnumdepth_ = lexrc.getInteger();
			break;

		case TC_TOCDEPTH:
			lexrc.next();
			tocdepth_ = lexrc.getInteger();
			break;

		// First step to support options
		case TC_CLASSOPTIONS:
			readClassOptions(lexrc);
			break;

		case TC_PREAMBLE:
			preamble_ = from_utf8(lexrc.getLongString("EndPreamble"));
			break;

		case TC_HTMLPREAMBLE:
			htmlpreamble_ = from_utf8(lexrc.getLongString("EndPreamble"));
			break;
		
		case TC_HTMLTOCSECTION:
			html_toc_section_ = from_utf8(trim(lexrc.getString()));
			break;

		case TC_ADDTOPREAMBLE:
			preamble_ += from_utf8(lexrc.getLongString("EndPreamble"));
			break;

		case TC_ADDTOHTMLPREAMBLE:
			htmlpreamble_ += from_utf8(lexrc.getLongString("EndPreamble"));
			break;

		case TC_PROVIDES: {
			lexrc.next();
			string const feature = lexrc.getString();
			lexrc.next();
			if (lexrc.getInteger())
				provides_.insert(feature);
			else
				provides_.erase(feature);
			break;
		}

		case TC_REQUIRES: {
			lexrc.eatLine();
			vector<string> const req 
				= getVectorFromString(lexrc.getString());
			requires_.insert(req.begin(), req.end());
			break;
		}

		case TC_DEFAULTMODULE: {
			lexrc.next();
			string const module = lexrc.getString();
			if (find(default_modules_.begin(), default_modules_.end(), module) == default_modules_.end())
				default_modules_.push_back(module);
			break;
		}

		case TC_PROVIDESMODULE: {
			lexrc.next();
			string const module = lexrc.getString();
			if (find(provided_modules_.begin(), provided_modules_.end(), module) == provided_modules_.end())
				provided_modules_.push_back(module);
			break;
		}

		case TC_EXCLUDESMODULE: {
			lexrc.next();
			string const module = lexrc.getString();
			// modules already have their own way to exclude other modules
			if (rt == MODULE) {
				LYXERR0("ExcludesModule tag cannot be used in a module!");
				break;
			}
			if (find(excluded_modules_.begin(), excluded_modules_.end(), module) == excluded_modules_.end())
				excluded_modules_.push_back(module);
			break;
		}

		case TC_LEFTMARGIN:	// left margin type
			if (lexrc.next())
				leftmargin_ = lexrc.getDocString();
			break;

		case TC_RIGHTMARGIN:	// right margin type
			if (lexrc.next())
				rightmargin_ = lexrc.getDocString();
			break;

		case TC_INSETLAYOUT: {
			if (!lexrc.next()) {
				lexrc.printError("No name given for InsetLayout: `$$Token'.");
				error = true;
				break;
			}
			docstring const name = subst(lexrc.getDocString(), '_', ' ');
			if (name.empty()) {
				string s = "Could not read name for InsetLayout: `$$Token' "
					+ lexrc.getString() + " is probably not valid UTF-8!";
				lexrc.printError(s);
				InsetLayout il;
				// Since we couldn't read the name, we just scan the rest
				// of the style and discard it.
				il.read(lexrc, *this);
				// Let's try to continue rather than abort.
				// error = true;
			} else if (hasInsetLayout(name)) {
				InsetLayout & il = insetlayoutlist_[name];
				error = !il.read(lexrc, *this);
			} else {
				InsetLayout il;
				il.setName(name);
				error = !il.read(lexrc, *this);
				if (!error)
					insetlayoutlist_[name] = il;
			}
			break;
		}

		case TC_FLOAT:
			error = !readFloat(lexrc);
			break;
		
		case TC_CITEFORMAT:
			readCiteFormat(lexrc);
			break;

		case TC_IFCOUNTER:
			ifcounter = true;
		case TC_COUNTER:
			if (lexrc.next()) {
				docstring const name = lexrc.getDocString();
				if (name.empty()) {
					string s = "Could not read name for counter: `$$Token' "
							+ lexrc.getString() + " is probably not valid UTF-8!";
					lexrc.printError(s.c_str());
					Counter c;
					// Since we couldn't read the name, we just scan the rest
					// and discard it.
					c.read(lexrc);
				} else
					error = !counters_.read(lexrc, name, !ifcounter);
			}
			else {
				lexrc.printError("No name given for style: `$$Token'.");
				error = true;
			}
			// reset flag
			ifcounter = false;
			break;

		case TC_TITLELATEXTYPE:
			readTitleType(lexrc);
			break;

		case TC_TITLELATEXNAME:
			if (lexrc.next())
				titlename_ = lexrc.getString();
			break;

		case TC_NOFLOAT:
			if (lexrc.next()) {
				string const nofloat = lexrc.getString();
				floatlist_.erase(nofloat);
			}
			break;
		} // end of switch

		// Note that this is triggered the first time through the loop unless
		// we hit a format tag.
		if (format != LAYOUT_FORMAT)
			return FORMAT_MISMATCH;
	}

	// at present, we abort if we encounter an error,
	// so there is no point continuing.
	if (error)
		return ERROR;

	if (rt != BASECLASS)
		return (error ? ERROR : OK);

	if (defaultlayout_.empty()) {
		LYXERR0("Error: Textclass '" << name_
						<< "' is missing a defaultstyle.");
		return ERROR;
	}
		
	// Try to erase "stdinsets" from the provides_ set. 
	// The
	//   Provides stdinsets 1
	// declaration simply tells us that the standard insets have been
	// defined. (It's found in stdinsets.inc but could also be used in
	// user-defined files.) There isn't really any such package. So we
	// might as well go ahead and erase it.
	// If we do not succeed, then it was not there, which means that
	// the textclass did not provide the definitions of the standard
	// insets. So we need to try to load them.
	int erased = provides_.erase("stdinsets");
	if (!erased) {
		FileName tmp = libFileSearch("layouts", "stdinsets.inc");

		if (tmp.empty()) {
			frontend::Alert::warning(_("Missing File"),
				_("Could not find stdinsets.inc! This may lead to data loss!"));
			error = true;
		} else if (!read(tmp, MERGE)) {
			frontend::Alert::warning(_("Corrupt File"),
				_("Could not read stdinsets.inc! This may lead to data loss!"));
			error = true;
		}
	}

	min_toclevel_ = Layout::NOT_IN_TOC;
	max_toclevel_ = Layout::NOT_IN_TOC;
	const_iterator lit = begin();
	const_iterator len = end();
	for (; lit != len; ++lit) {
		int const toclevel = lit->toclevel;
		if (toclevel != Layout::NOT_IN_TOC) {
			if (min_toclevel_ == Layout::NOT_IN_TOC)
				min_toclevel_ = toclevel;
			else
				min_toclevel_ = min(min_toclevel_, toclevel);
			max_toclevel_ = max(max_toclevel_, toclevel);
		}
	}
	LYXERR(Debug::TCLASS, "Minimum TocLevel is " << min_toclevel_
		<< ", maximum is " << max_toclevel_);

	return (error ? ERROR : OK);
}
Example #15
0
void ConverterCache::add(FileName const & orig_from, string const & to_format,
		FileName const & converted_file) const
{
	if (!lyxrc.use_converter_cache || orig_from.empty() ||
	    converted_file.empty())
		return;
	LYXERR(Debug::FILES, ' ' << orig_from
			     << ' ' << to_format << ' ' << converted_file);

	// FIXME: Should not hardcode this (see bug 3819 for details)
	if (to_format == "pstex") {
		FileName const converted_eps(changeExtension(converted_file.absFileName(), "eps"));
		add(orig_from, "eps", converted_eps);
	} else if (to_format == "pdftex") {
		FileName const converted_pdf(changeExtension(converted_file.absFileName(), "pdf"));
		add(orig_from, "pdf", converted_pdf);
	}

	// Is the file in the cache already?
	CacheItem * item = pimpl_->find(orig_from, to_format);

	time_t const timestamp = orig_from.lastModified();
	Mover const & mover = getMover(to_format);
	if (item) {
		LYXERR(Debug::FILES, "ConverterCache::add(" << orig_from << "):\n"
					"The file is already in the cache.");
		// First test for timestamp
		if (timestamp == item->timestamp) {
			LYXERR(Debug::FILES, "Same timestamp.");
			return;
		}
		// Maybe the contents is still the same?
		item->timestamp = timestamp;
		unsigned long const checksum = orig_from.checksum();
		if (checksum == item->checksum) {
			LYXERR(Debug::FILES, "Same checksum.");
			return;
		}
		item->checksum = checksum;
		if (!mover.copy(converted_file, item->cache_name,
		              onlyFileName(item->cache_name.absFileName()))) {
			LYXERR(Debug::FILES, "Could not copy file " << orig_from << " to "
				<< item->cache_name);
		} else if (!item->cache_name.changePermission(0600)) {
			LYXERR(Debug::FILES, "Could not change file mode"
				<< item->cache_name);
		}
	} else {
		CacheItem new_item(orig_from, to_format, timestamp,
				orig_from.checksum());
		if (mover.copy(converted_file, new_item.cache_name,
		              onlyFileName(new_item.cache_name.absFileName()))) {
			if (!new_item.cache_name.changePermission(0600)) {
				LYXERR(Debug::FILES, "Could not change file mode"
					<< new_item.cache_name);
			}
			FormatCache & format_cache = pimpl_->cache[orig_from];
			if (format_cache.from_format.empty())
				format_cache.from_format =
					formats.getFormatFromFile(orig_from);
			format_cache.cache[to_format] = new_item;
		} else
			LYXERR(Debug::FILES, "ConverterCache::add(" << orig_from << "):\n"
						"Could not copy file.");
	}
}
Example #16
0
// Much of this is borrowed from LayoutFileList::read()
bool ModuleList::read()
{
	FileName const real_file = libFileSearch("", "lyxmodules.lst");
	LYXERR(Debug::TCLASS, "Reading modules from `" << real_file << '\'');

	if (real_file.empty()) {
		LYXERR0("unable to find modules file `lyxmodules.lst'.\n"
			<< "No modules will be available.");
		return false;
	}

	Lexer lex;
	if (!lex.setFile(real_file)) {
		LYXERR0("lyxlex was not able to set file: "
			<< real_file << ".\nNo modules will be available.");
		return false;
	}

	if (!lex.isOK()) {
		LYXERR0("unable to open modules file  `"
			<< to_utf8(makeDisplayPath(real_file.absFileName(), 1000))
			<< "'\nNo modules will be available.");
		return false;
	}

	bool finished = false;
	// Parse modules files
	LYXERR(Debug::TCLASS, "Starting parsing of lyxmodules.lst");
	while (lex.isOK() && !finished) {
		LYXERR(Debug::TCLASS, "\tline by line");
		switch (lex.lex()) {
		case Lexer::LEX_FEOF:
			finished = true;
			break;
		default:
			string const modname = lex.getString();
			LYXERR(Debug::TCLASS, "Module name: " << modname);
			if (!lex.next())
				break;
			string const fname = lex.getString();
			LYXERR(Debug::TCLASS, "Filename: " << fname);
			if (!lex.next(true))
				break;
			string const desc = lex.getString();
			LYXERR(Debug::TCLASS, "Description: " << desc);
			//FIXME Add packages
			if (!lex.next())
				break;
			string str = lex.getString();
			LYXERR(Debug::TCLASS, "Packages: " << str);
			vector<string> pkgs;
			while (!str.empty()) {
				string p;
				str = split(str, p, ',');
				pkgs.push_back(p);
			}
			if (!lex.next())
				break;
			str = lex.getString();
			LYXERR(Debug::TCLASS, "Required: " << str);
			vector<string> req;
			while (!str.empty()) {
				string p;
				str = split(str, p, '|');
				req.push_back(p);
			}
			if (!lex.next())
				break;
			str = lex.getString();
			LYXERR(Debug::TCLASS, "Excluded: " << str);
			vector<string> exc;
			while (!str.empty()) {
				string p;
				str = split(str, p, '|');
				exc.push_back(p);
			}
			if (!lex.next())
				break;
			string const catgy = lex.getString();
			LYXERR(Debug::TCLASS, "Category: " << catgy);
			if (!lex.next())
				break;
			bool const local = lex.getString() == "true";
			LYXERR(Debug::TCLASS, "Local: " << local);
			// This code is run when we have
			// modName, fname, desc, pkgs, req, exc, catgy, and local
			addLayoutModule(modname, fname, desc, pkgs, req, exc, catgy, local);
		} // end switch
	} //end while

	LYXERR(Debug::TCLASS, "End of parsing of lyxmodules.lst");

	if (!theModuleList.empty())
		sort(theModuleList.begin(), theModuleList.end(), ModuleSorter());
	return true;
}
Example #17
0
// Returns a local socket already in the "listen" state (or -1 in case
// of error). The first argument is the socket address, the second
// is the length of the queue for connections. If successful, a socket
// special file 'name' will be created in the filesystem.
int listen(FileName const & name, int queue)
{
	int fd; // File descriptor for the socket
	sockaddr_un addr; // Structure that hold the socket address

	// We use 'localname' to fill 'addr'
	string const localname = name.toFilesystemEncoding();
	string::size_type len = localname.size();
	// the field sun_path in sockaddr_un is a char[108]
	if (len > 107) {
		LYXERR0("lyx: Socket address '" << name.absFileName() << "' too long.");
		return -1;
	}
	// Synonims for AF_UNIX are AF_LOCAL and AF_FILE
	addr.sun_family = AF_UNIX;
	localname.copy(addr.sun_path, 107);
	addr.sun_path[len] = '\0';

	// This creates a file descriptor for the socket
	// Synonims for PF_UNIX are PF_LOCAL and PF_FILE
	// For local sockets, the protocol is always 0
	// socket() returns -1 in case of error
	if ((fd = ::socket(PF_UNIX, SOCK_STREAM, 0))== -1) {
		LYXERR0("lyx: Could not create socket descriptor: "
		       << strerror(errno));
		return -1;
	}

	// Set NONBLOCK mode for the file descriptor
	if (::fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
		LYXERR0("lyx: Could not set NONBLOCK mode for socket descriptor: "
		     << strerror(errno));
		::close(fd);
		return -1;
	}

	// bind() gives the local address 'name' for 'fd', also creating
	// the socket special file in the filesystem. bind() returns -1
	// in case of error
	if ((::bind (fd, reinterpret_cast<sockaddr *>(&addr), SUN_LEN(&addr))) == -1) {
		LYXERR0("lyx: Could not bind address '" << name.absFileName()
		       << "' to socket descriptor: " << strerror(errno));
		::close(fd);
		name.removeFile();
		return -1;
	}

	// Puts the socket in listen state, that is, ready to accept
	// connections. The second parameter of listen() defines the
	// maximum length the queue of pending connections may grow to.
	// It is not a restriction on the number of connections the socket
	// can accept. Returns -1 in case of error
	if (::listen (fd, queue) == -1) {
		LYXERR0("lyx: Could not put socket in 'listen' state: "
		       << strerror(errno));
		::close(fd);
		name.removeFile();
		return -1;
	}

	return fd;
}
Example #18
0
bool Mover::copy(FileName const & from, FileName const & to) const
{
	return do_copy(from, to, to.absFileName());
}
Example #19
0
FileName GuiClipboard::getPastedGraphicsFileName(Cursor const & cur,
	Clipboard::GraphicsType & type) const
{
	// create file dialog filter according to the existing types in the clipboard
	vector<Clipboard::GraphicsType> types;
	if (hasGraphicsContents(Clipboard::EmfGraphicsType))
		types.push_back(Clipboard::EmfGraphicsType);
	if (hasGraphicsContents(Clipboard::WmfGraphicsType))
		types.push_back(Clipboard::WmfGraphicsType);
	if (hasGraphicsContents(Clipboard::LinkBackGraphicsType))
		types.push_back(Clipboard::LinkBackGraphicsType);
	if (hasGraphicsContents(Clipboard::PdfGraphicsType))
		types.push_back(Clipboard::PdfGraphicsType);
	if (hasGraphicsContents(Clipboard::PngGraphicsType))
		types.push_back(Clipboard::PngGraphicsType);
	if (hasGraphicsContents(Clipboard::JpegGraphicsType))
		types.push_back(Clipboard::JpegGraphicsType);
	
	LASSERT(!types.empty(), /**/);
	
	// select prefered type if AnyGraphicsType was passed
	if (type == Clipboard::AnyGraphicsType)
		type = types.front();
	
	// which extension?
	map<Clipboard::GraphicsType, string> extensions;
	map<Clipboard::GraphicsType, docstring> typeNames;
	
	extensions[Clipboard::EmfGraphicsType] = "emf";
	extensions[Clipboard::WmfGraphicsType] = "wmf";
	extensions[Clipboard::LinkBackGraphicsType] = "linkback";
	extensions[Clipboard::PdfGraphicsType] = "pdf";
	extensions[Clipboard::PngGraphicsType] = "png";
	extensions[Clipboard::JpegGraphicsType] = "jpeg";
	
	typeNames[Clipboard::EmfGraphicsType] = _("Enhanced Metafile");
	typeNames[Clipboard::WmfGraphicsType] = _("Windows Metafile");
	typeNames[Clipboard::LinkBackGraphicsType] = _("LinkBack PDF");
	typeNames[Clipboard::PdfGraphicsType] = _("PDF");
	typeNames[Clipboard::PngGraphicsType] = _("PNG");
	typeNames[Clipboard::JpegGraphicsType] = _("JPEG");
	
	// find unused filename with primary extension
	string document_path = cur.buffer()->fileName().onlyPath().absFileName();
	unsigned newfile_number = 0;
	FileName filename;
	do {
		++newfile_number;
		filename = FileName(addName(document_path,
			to_utf8(_("pasted"))
			+ convert<string>(newfile_number) + "."
			+ extensions[type]));
	} while (filename.isReadableFile());
	
	while (true) {
		// create file type filter, putting the prefered on to the front
		QStringList filter;
		for (size_t i = 0; i != types.size(); ++i) {
			docstring s = bformat(_("%1$s Files"), typeNames[types[i]])
				+ " (*." + from_ascii(extensions[types[i]]) + ")";
			if (types[i] == type)
				filter.prepend(toqstr(s));
			else
				filter.append(toqstr(s));
		}
		filter = fileFilters(filter.join(";;"));
		
		// show save dialog for the graphic
		FileDialog dlg(qt_("Choose a filename to save the pasted graphic as"));
		FileDialog::Result result =
		dlg.save(toqstr(filename.onlyPath().absFileName()), filter,
			 toqstr(filename.onlyFileName()));
		
		if (result.first == FileDialog::Later)
			return FileName();
		
		string newFilename = fromqstr(result.second);
		if (newFilename.empty()) {
			cur.bv().message(_("Canceled."));
			return FileName();
		}
		filename.set(newFilename);
		
		// check the extension (the user could have changed it)
		if (!suffixIs(ascii_lowercase(filename.absFileName()),
			      "." + extensions[type])) {
			// the user changed the extension. Check if the type is available
			size_t i;
			for (i = 1; i != types.size(); ++i) {
				if (suffixIs(ascii_lowercase(filename.absFileName()),
					     "." + extensions[types[i]])) {
					type = types[i];
					break;
				}
			}
			
			// invalid extension found, or none at all. In the latter
			// case set the default extensions.
			if (i == types.size()
			    && filename.onlyFileName().find('.') == string::npos) {
				filename.changeExtension("." + extensions[type]);
			}
		}
		
		// check whether the file exists and warn the user
		if (!filename.exists())
			break;
		int ret = frontend::Alert::prompt(
			_("Overwrite external file?"),
			bformat(_("File %1$s already exists, do you want to overwrite it?"),
			from_utf8(filename.absFileName())), 1, 1, _("&Overwrite"), _("&Cancel"));
		if (ret == 0)
			// overwrite, hence break the dialog loop
			break;
		
		// not overwrite, hence show the dialog again (i.e. loop)
	}
	
	return filename;
}
Example #20
0
bool Mover::rename(FileName const & from,
		   FileName const & to) const
{
	return do_rename(from, to, to.absFileName());
}
Example #21
0
FileName GuiClipboard::getAsGraphics(Cursor const & cur, GraphicsType type) const
{
	// get the filename from the user
	FileName filename = getPastedGraphicsFileName(cur, type);
	if (filename.empty())
		return FileName();

	// handle image cases first
	if (type == PngGraphicsType || type == JpegGraphicsType) {
		// get image from QImage from clipboard
		QImage image = qApp->clipboard()->image();
		if (image.isNull()) {
			LYXERR(Debug::ACTION, "No image in clipboard");
			return FileName();
		}

		// convert into graphics format
		QByteArray ar;
		QBuffer buffer(&ar);
		buffer.open(QIODevice::WriteOnly);
		if (type == PngGraphicsType)
			image.save(toqstr(filename.absFileName()), "PNG");
		else if (type == JpegGraphicsType)
			image.save(toqstr(filename.absFileName()), "JPEG");
		else
			LATTEST(false);
		
		return filename;
	}
	
	// get mime for type
	QString mime;
	switch (type) {
	case PdfGraphicsType: mime = pdfMimeType(); break;
	case LinkBackGraphicsType: mime = pdfMimeType(); break;
	case EmfGraphicsType: mime = emfMimeType(); break;
	case WmfGraphicsType: mime = wmfMimeType(); break;
	default: LASSERT(false, return FileName());
	}
	
	// get data
	if (!cache_.hasFormat(mime))
		return FileName();
	// data from ourself or some other LyX instance
	QByteArray const ar = cache_.data(mime);
	LYXERR(Debug::ACTION, "Getting from clipboard: mime = " << mime.constData()
	       << "length = " << ar.count());

	QFile f(toqstr(filename.absFileName()));
	if (!f.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
		LYXERR(Debug::ACTION, "Error opening file "
		       << filename.absFileName() << " for writing");
		return FileName();
	}
	
	// write the (LinkBack) PDF data
	f.write(ar);
	if (type == LinkBackGraphicsType) {
#ifdef Q_WS_MACX
		void const * linkBackData;
		unsigned linkBackLen;
		getLinkBackData(&linkBackData, &linkBackLen);
		f.write((char *)linkBackData, linkBackLen);
		quint32 pdfLen = ar.size();
		QDataStream ds(&f);
		ds << pdfLen; // big endian by default
#else
		// only non-Mac this should never happen
		LATTEST(false);
#endif // Q_WS_MACX
	}

	f.close();
	return filename;
}
Example #22
0
void ExportData::addExternalFile(string const & format,
				 FileName const & sourceName)
{
	addExternalFile(format, sourceName, onlyFileName(sourceName.absFileName()));
}