mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-25 05:55:34 +00:00
Implement VCS copy and rename
The advantage of having this in LyX is the intelligent file name handling of included files. Implementation as discussed on the list, but ensure also that an attempt to use locked files fails.
This commit is contained in:
parent
067fbe49cd
commit
0526eb9d47
@ -19147,6 +19147,109 @@ co -f -u<version> <file-name>
|
||||
|
||||
\begin_layout Subsubsection
|
||||
|
||||
\family sans
|
||||
Copy
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
This will create a copy of the current document.
|
||||
Since RCS does not support copy operations natively, the version history
|
||||
is not preserved, and the copy is added as a new file.
|
||||
It requires a clean document without any changes since the last checkin.
|
||||
You are asked for a file name and a description of the copy operation.
|
||||
After that the copy is created, both locally and in the repository.
|
||||
If the parent directories of the copied and original document differ, all
|
||||
relative paths of included files of the copy are adjusted (like in
|
||||
\family sans
|
||||
File\SpecialChar \menuseparator
|
||||
Save As
|
||||
\family default
|
||||
\SpecialChar \ldots{}
|
||||
).
|
||||
Finally, the copy is loaded instead of the original document.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Labeling
|
||||
\labelwidthstring 00.00.0000
|
||||
RCS
|
||||
\begin_inset space ~
|
||||
\end_inset
|
||||
|
||||
commands:
|
||||
\begin_inset space ~
|
||||
\end_inset
|
||||
|
||||
|
||||
\begin_inset Newline newline
|
||||
\end_inset
|
||||
|
||||
Copy
|
||||
\begin_inset Flex Code
|
||||
status collapsed
|
||||
|
||||
\begin_layout Plain Layout
|
||||
|
||||
\family typewriter
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
<file-name>
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
|
||||
\end_layout
|
||||
|
||||
\end_inset
|
||||
|
||||
to
|
||||
\begin_inset Flex Code
|
||||
status collapsed
|
||||
|
||||
\begin_layout Plain Layout
|
||||
|
||||
\family typewriter
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
<new-file-name>
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
|
||||
\end_layout
|
||||
|
||||
\end_inset
|
||||
|
||||
|
||||
\begin_inset Newline newline
|
||||
\end_inset
|
||||
|
||||
|
||||
\begin_inset Flex Code
|
||||
status collapsed
|
||||
|
||||
\begin_layout Plain Layout
|
||||
ci -q -u
|
||||
\family typewriter
|
||||
-i
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
<new-file-name>
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
|
||||
\end_layout
|
||||
|
||||
\end_inset
|
||||
|
||||
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
|
||||
\family sans
|
||||
Undo Last Checkin
|
||||
\end_layout
|
||||
@ -19551,6 +19654,237 @@ CVS command:
|
||||
cvs -q unedit "<file-name>"
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
|
||||
\family sans
|
||||
Copy
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
This will create a copy of the current document.
|
||||
Since CVS does not support copy operations natively, the version history
|
||||
is not preserved, and the copy is added as a new file.
|
||||
It requires a clean document without any changes since the last checkin.
|
||||
You are asked for a file name and a description of the copy operation.
|
||||
After that the copy is created, both locally and in the repository.
|
||||
If the parent directories of the copied and original document differ, all
|
||||
relative paths of included files of the copy are adjusted (like in
|
||||
\family sans
|
||||
File\SpecialChar \menuseparator
|
||||
Save As
|
||||
\family default
|
||||
\SpecialChar \ldots{}
|
||||
).
|
||||
Finally, the copy is loaded instead of the original document.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Labeling
|
||||
\labelwidthstring 00.00.0000
|
||||
CVS
|
||||
\begin_inset space ~
|
||||
\end_inset
|
||||
|
||||
commands:
|
||||
\begin_inset space ~
|
||||
\end_inset
|
||||
|
||||
|
||||
\begin_inset Newline newline
|
||||
\end_inset
|
||||
|
||||
Copy
|
||||
\begin_inset Flex Code
|
||||
status collapsed
|
||||
|
||||
\begin_layout Plain Layout
|
||||
|
||||
\family typewriter
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
<file-name>
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
|
||||
\end_layout
|
||||
|
||||
\end_inset
|
||||
|
||||
to
|
||||
\begin_inset Flex Code
|
||||
status collapsed
|
||||
|
||||
\begin_layout Plain Layout
|
||||
|
||||
\family typewriter
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
<new-file-name>
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
|
||||
\end_layout
|
||||
|
||||
\end_inset
|
||||
|
||||
|
||||
\begin_inset Newline newline
|
||||
\end_inset
|
||||
|
||||
|
||||
\begin_inset Flex Code
|
||||
status collapsed
|
||||
|
||||
\begin_layout Plain Layout
|
||||
cvs -q add
|
||||
\family typewriter
|
||||
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
<new-file-name>
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
|
||||
\end_layout
|
||||
|
||||
\end_inset
|
||||
|
||||
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
|
||||
\family sans
|
||||
Rename
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
This will rename the current document.
|
||||
Since CVS does not support rename operations natively, the version history
|
||||
is not preserved, the renamed document is added as a new file, and the
|
||||
original document is deleted.
|
||||
It requires a clean document without any changes since the last checkin.
|
||||
You are asked for a file name and a description of the rename operation.
|
||||
After that the document is renamed, both locally and in the repository.
|
||||
If the parent directories of the new and old file names differ, all relative
|
||||
paths of included files are adjusted (like in
|
||||
\family sans
|
||||
File\SpecialChar \menuseparator
|
||||
Save As
|
||||
\family default
|
||||
\SpecialChar \ldots{}
|
||||
).
|
||||
Finally, the document is reloaded using the new name.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Labeling
|
||||
\labelwidthstring 00.00.0000
|
||||
CVS
|
||||
\begin_inset space ~
|
||||
\end_inset
|
||||
|
||||
commands:
|
||||
\begin_inset space ~
|
||||
\end_inset
|
||||
|
||||
|
||||
\begin_inset Newline newline
|
||||
\end_inset
|
||||
|
||||
Rename
|
||||
\begin_inset Flex Code
|
||||
status collapsed
|
||||
|
||||
\begin_layout Plain Layout
|
||||
|
||||
\family typewriter
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
<file-name>
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
|
||||
\end_layout
|
||||
|
||||
\end_inset
|
||||
|
||||
to
|
||||
\begin_inset Flex Code
|
||||
status collapsed
|
||||
|
||||
\begin_layout Plain Layout
|
||||
|
||||
\family typewriter
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
<new-file-name>
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
|
||||
\end_layout
|
||||
|
||||
\end_inset
|
||||
|
||||
|
||||
\begin_inset Newline newline
|
||||
\end_inset
|
||||
|
||||
|
||||
\begin_inset Flex Code
|
||||
status collapsed
|
||||
|
||||
\begin_layout Plain Layout
|
||||
cvs -q add
|
||||
\family typewriter
|
||||
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
<new-file-name>
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
|
||||
\end_layout
|
||||
|
||||
\end_inset
|
||||
|
||||
|
||||
\begin_inset Newline newline
|
||||
\end_inset
|
||||
|
||||
|
||||
\begin_inset Flex Code
|
||||
status collapsed
|
||||
|
||||
\begin_layout Plain Layout
|
||||
cvs -q remove
|
||||
\family typewriter
|
||||
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
<file-name>
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
|
||||
\end_layout
|
||||
|
||||
\end_inset
|
||||
|
||||
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
Update of the local directory checkout from repository
|
||||
\end_layout
|
||||
@ -19926,6 +20260,168 @@ svn revert -q
|
||||
\end_inset
|
||||
|
||||
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
|
||||
\family sans
|
||||
Copy
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
This will create a copy of the current document including the version history.
|
||||
It requires a clean document without any changes since the last checkin.
|
||||
You are asked for a file name and a description of the copy operation.
|
||||
After that the copy is created, both locally and in the repository.
|
||||
If the parent directories of the copied and original document differ, all
|
||||
relative paths of included files of the copy are adjusted (like in
|
||||
\family sans
|
||||
File\SpecialChar \menuseparator
|
||||
Save As
|
||||
\family default
|
||||
\SpecialChar \ldots{}
|
||||
).
|
||||
Finally, the copy is loaded instead of the original document.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Labeling
|
||||
\labelwidthstring 00.00.0000
|
||||
SVN
|
||||
\begin_inset space ~
|
||||
\end_inset
|
||||
|
||||
commands:
|
||||
\begin_inset space ~
|
||||
\end_inset
|
||||
|
||||
|
||||
\begin_inset Newline newline
|
||||
\end_inset
|
||||
|
||||
|
||||
\begin_inset Flex Code
|
||||
status collapsed
|
||||
|
||||
\begin_layout Plain Layout
|
||||
svn copy -q
|
||||
\family typewriter
|
||||
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
<file-name>
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
<new-file-name>
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
|
||||
\end_layout
|
||||
|
||||
\end_inset
|
||||
|
||||
|
||||
\begin_inset Newline newline
|
||||
\end_inset
|
||||
|
||||
|
||||
\begin_inset Flex Code
|
||||
status collapsed
|
||||
|
||||
\begin_layout Plain Layout
|
||||
svn commit
|
||||
\end_layout
|
||||
|
||||
\end_inset
|
||||
|
||||
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
|
||||
\family sans
|
||||
Rename
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
This will rename the current document including the version history.
|
||||
It requires a clean document without any changes since the last checkin.
|
||||
You are asked for a file name and a description of the rename operation.
|
||||
After that the document is renamed, both locally and in the repository.
|
||||
If the parent directories of the new and old file names differ, all relative
|
||||
paths of included files are adjusted (like in
|
||||
\family sans
|
||||
File\SpecialChar \menuseparator
|
||||
Save As
|
||||
\family default
|
||||
\SpecialChar \ldots{}
|
||||
).
|
||||
Finally, the document is reloaded using the new name.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Labeling
|
||||
\labelwidthstring 00.00.0000
|
||||
SVN
|
||||
\begin_inset space ~
|
||||
\end_inset
|
||||
|
||||
commands:
|
||||
\begin_inset space ~
|
||||
\end_inset
|
||||
|
||||
|
||||
\begin_inset Newline newline
|
||||
\end_inset
|
||||
|
||||
|
||||
\begin_inset Flex Code
|
||||
status collapsed
|
||||
|
||||
\begin_layout Plain Layout
|
||||
svn move -q
|
||||
\family typewriter
|
||||
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
<file-name>
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
<new-file-name>
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
|
||||
\end_layout
|
||||
|
||||
\end_inset
|
||||
|
||||
|
||||
\begin_inset Newline newline
|
||||
\end_inset
|
||||
|
||||
|
||||
\begin_inset Flex Code
|
||||
status collapsed
|
||||
|
||||
\begin_layout Plain Layout
|
||||
svn commit
|
||||
\end_layout
|
||||
|
||||
\end_inset
|
||||
|
||||
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
|
@ -83,7 +83,7 @@
|
||||
\begin_body
|
||||
|
||||
\begin_layout Section*
|
||||
LFUNs documentation automatically generated 2013-02-03
|
||||
LFUNs documentation automatically generated 2013-02-05
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
@ -4142,6 +4142,68 @@ Syntax vc-register
|
||||
Origin Lgb, 1 Jul 1997
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsection*
|
||||
LFUN_VC_RENAME
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
Action Renames the document to another name.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
Notion Renaming with revision history is only supported by SVN.
|
||||
For CVS it is simulated by adding the document under a new name and deleting
|
||||
the old one.
|
||||
For RCS it is not supported.
|
||||
Disabled if uncommitted changes exist.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
Syntax vc-rename <FILENAME>
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
Params <FILENAME>: New name of the document.
|
||||
\begin_inset Newline newline
|
||||
\end_inset
|
||||
|
||||
A file dialog is opened if no filename is given.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
Origin gb, 05 Feb 2013
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsection*
|
||||
LFUN_VC_COPY
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
Action Copies the document to another name.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
Notion Copying with revision history is only supported by SVN.
|
||||
For RCS and CVS it is simulated by adding the document under a new name.
|
||||
Disabled if uncommitted changes exist.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
Syntax vc-copy <FILENAME>
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
Params <FILENAME>: New name of the document.
|
||||
\begin_inset Newline newline
|
||||
\end_inset
|
||||
|
||||
A file dialog is opened if no filename is given.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
Origin gb, 05 Feb 2013
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsection*
|
||||
LFUN_VC_CHECK_IN
|
||||
\end_layout
|
||||
|
@ -74,6 +74,8 @@ Menuset
|
||||
OptItem "Register...|R" "vc-register"
|
||||
OptItem "Check In Changes...|I" "vc-check-in"
|
||||
OptItem "Check Out for Edit|O" "vc-check-out"
|
||||
OptItem "Copy|p" "vc-copy"
|
||||
OptItem "Rename|R" "vc-rename"
|
||||
OptItem "Update Local Directory From Repository|d" "vc-repo-update"
|
||||
OptItem "Revert to Repository Version|v" "vc-revert"
|
||||
OptItem "Undo Last Check In|U" "vc-undo-last"
|
||||
|
@ -453,6 +453,9 @@ enum FuncCode
|
||||
LFUN_BRANCH_MASTER_ACTIVATE, // spitz 20120930
|
||||
LFUN_BRANCH_MASTER_DEACTIVATE, // spitz 20120930
|
||||
LFUN_ENVIRONMENT_SPLIT, // spitz 20121223
|
||||
LFUN_VC_RENAME, // gb 20130205
|
||||
LFUN_VC_COPY, // gb 20130205
|
||||
// 355
|
||||
LFUN_LASTACTION // end of the table
|
||||
};
|
||||
|
||||
|
@ -2146,6 +2146,34 @@ void LyXAction::init()
|
||||
* \endvar
|
||||
*/
|
||||
{ LFUN_VC_REGISTER, "vc-register", ReadOnly, System },
|
||||
/*!
|
||||
* \var lyx::FuncCode lyx::LFUN_VC_RENAME
|
||||
* \li Action: Renames the document to another name.
|
||||
* \li Notion: Renaming with revision history is only supported by SVN.
|
||||
For CVS it is simulated by adding the document under a new
|
||||
name and deleting the old one. For RCS it is not supported.
|
||||
Disabled if uncommitted changes exist.
|
||||
* \li Syntax: vc-rename <FILENAME>
|
||||
* \li Params: <FILENAME>: New name of the document.\n
|
||||
* A file dialog is opened if no filename is given.
|
||||
* \li Origin: gb, 05 Feb 2013
|
||||
* \endvar
|
||||
*/
|
||||
{ LFUN_VC_RENAME, "vc-rename", ReadOnly, System },
|
||||
/*!
|
||||
* \var lyx::FuncCode lyx::LFUN_VC_COPY
|
||||
* \li Action: Copies the document to another name.
|
||||
* \li Notion: Copying with revision history is only supported by SVN.
|
||||
For RCS and CVS it is simulated by adding the document
|
||||
under a new name.
|
||||
Disabled if uncommitted changes exist.
|
||||
* \li Syntax: vc-copy <FILENAME>
|
||||
* \li Params: <FILENAME>: New name of the document.\n
|
||||
* A file dialog is opened if no filename is given.
|
||||
* \li Origin: gb, 05 Feb 2013
|
||||
* \endvar
|
||||
*/
|
||||
{ LFUN_VC_COPY, "vc-copy", ReadOnly, System },
|
||||
/*!
|
||||
* \var lyx::FuncCode lyx::LFUN_VC_CHECK_IN
|
||||
* \li Action: Checks-in/commits the changes of the registered file to the repository.
|
||||
|
@ -173,6 +173,44 @@ bool LyXVC::registrer()
|
||||
}
|
||||
|
||||
|
||||
string LyXVC::rename(FileName const & fn)
|
||||
{
|
||||
LYXERR(Debug::LYXVC, "LyXVC: rename");
|
||||
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->rename(fn, to_utf8(response));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
LyXVC::CommandResult LyXVC::checkIn(string & log)
|
||||
{
|
||||
LYXERR(Debug::LYXVC, "LyXVC: checkIn");
|
||||
@ -273,6 +311,7 @@ string LyXVC::toggleReadOnly()
|
||||
return log;
|
||||
}
|
||||
case VCS::NOLOCKING:
|
||||
case VCS::UNVERSIONED:
|
||||
break;
|
||||
}
|
||||
return string();
|
||||
@ -282,7 +321,7 @@ string LyXVC::toggleReadOnly()
|
||||
bool LyXVC::inUse() const
|
||||
{
|
||||
if (vcs)
|
||||
return true;
|
||||
return vcs->status() != VCS::UNVERSIONED;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -328,6 +367,20 @@ string LyXVC::revisionInfo(RevisionInfo const info) const
|
||||
}
|
||||
|
||||
|
||||
bool LyXVC::renameEnabled() const
|
||||
{
|
||||
if (!inUse())
|
||||
return false;
|
||||
return vcs->renameEnabled();
|
||||
}
|
||||
|
||||
|
||||
bool LyXVC::copyEnabled() const
|
||||
{
|
||||
return inUse();
|
||||
}
|
||||
|
||||
|
||||
bool LyXVC::checkOutEnabled() const
|
||||
{
|
||||
return vcs && vcs->checkOutEnabled();
|
||||
@ -340,6 +393,12 @@ bool LyXVC::checkInEnabled() const
|
||||
}
|
||||
|
||||
|
||||
bool LyXVC::isCheckInWithConfirmation() const
|
||||
{
|
||||
return vcs && vcs->isCheckInWithConfirmation();
|
||||
}
|
||||
|
||||
|
||||
bool LyXVC::lockingToggleEnabled() const
|
||||
{
|
||||
return vcs && vcs->lockingToggleEnabled();
|
||||
|
12
src/LyXVC.h
12
src/LyXVC.h
@ -84,11 +84,22 @@ public:
|
||||
// by the next multiple messages on the top of the processed dispatch
|
||||
// machinery.
|
||||
|
||||
///
|
||||
std::string rename(support::FileName const &);
|
||||
/// Does the current VC support this operation?
|
||||
bool renameEnabled() const;
|
||||
///
|
||||
std::string copy(support::FileName const &);
|
||||
/// Does the current VC support this operation?
|
||||
bool copyEnabled() const;
|
||||
|
||||
/// Unlock and commit changes.
|
||||
/// \p log is non-empty on success and may be empty on failure.
|
||||
CommandResult checkIn(std::string & log);
|
||||
/// Does the current VC support this operation?
|
||||
bool checkInEnabled() const;
|
||||
/// Should a log message be provided for next checkin?
|
||||
bool isCheckInWithConfirmation() const;
|
||||
|
||||
/// Lock/update and prepare to edit document. Returns log.
|
||||
std::string checkOut();
|
||||
@ -146,6 +157,7 @@ public:
|
||||
std::string toggleReadOnly();
|
||||
|
||||
/// Is the document under administration by VCS?
|
||||
/// returns false for unregistered documents in a path managed by VCS
|
||||
bool inUse() const;
|
||||
|
||||
/// Returns the RCS + version number for messages
|
||||
|
@ -233,6 +233,35 @@ void RCS::registrer(string const & msg)
|
||||
}
|
||||
|
||||
|
||||
bool RCS::renameEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
string RCS::rename(support::FileName const & /*newFile*/, string const & /*msg*/)
|
||||
{
|
||||
// not implemented, since a left-over file.lyx,v would be confusing.
|
||||
return string();
|
||||
}
|
||||
|
||||
|
||||
string RCS::copy(support::FileName const & newFile, string const & msg)
|
||||
{
|
||||
// RCS has no real copy command, so we create a poor mans version
|
||||
support::FileName const oldFile(owner_->absFileName());
|
||||
if (!oldFile.copyTo(newFile))
|
||||
return string();
|
||||
FileName path(oldFile.onlyPath());
|
||||
string relFile(to_utf8(newFile.relPath(path.absFileName())));
|
||||
string cmd = "ci -q -u -i -t-\"";
|
||||
cmd += msg;
|
||||
cmd += "\" ";
|
||||
cmd += quoteName(relFile);
|
||||
return doVCCommand(cmd, path) ? string() : "RCS: Proceeded";
|
||||
}
|
||||
|
||||
|
||||
LyXVC::CommandResult RCS::checkIn(string const & msg, string & log)
|
||||
{
|
||||
int ret = doVCCommand("ci -q -u -m\"" + msg + "\" "
|
||||
@ -369,7 +398,7 @@ bool RCS::toggleReadOnlyEnabled()
|
||||
// This got broken somewhere along lfuns dispatch reorganization.
|
||||
// reloadBuffer would be needed after this, but thats problematic
|
||||
// since we are inside Buffer::dispatch.
|
||||
// return true;
|
||||
// return return status() != UNVERSIONED;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -518,6 +547,7 @@ void CVS::scanMaster()
|
||||
LYXERR(Debug::LYXVC, "\tlooking for `" << tmpf << '\'');
|
||||
string line;
|
||||
static regex const reg("/(.*)/(.*)/(.*)/(.*)/(.*)");
|
||||
vcstatus = UNVERSIONED;
|
||||
while (getline(ifs, line)) {
|
||||
LYXERR(Debug::LYXVC, "\t line: " << line);
|
||||
if (contains(line, tmpf)) {
|
||||
@ -711,6 +741,39 @@ void CVS::registrer(string const & msg)
|
||||
}
|
||||
|
||||
|
||||
bool CVS::renameEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
string CVS::rename(support::FileName const & newFile, string const & msg)
|
||||
{
|
||||
// CVS has no real rename command, so we create a poor mans version
|
||||
support::FileName const oldFile(owner_->absFileName());
|
||||
string ret = copy(newFile, msg);
|
||||
if (ret.empty())
|
||||
return ret;
|
||||
string cmd = "cvs -q remove -m \"" + msg + "\" " +
|
||||
quoteName(oldFile.onlyFileName());
|
||||
FileName path(oldFile.onlyPath());
|
||||
return doVCCommand(cmd, path) ? string() : ret;
|
||||
}
|
||||
|
||||
|
||||
string CVS::copy(support::FileName const & newFile, string const & msg)
|
||||
{
|
||||
// CVS has no real copy command, so we create a poor mans version
|
||||
support::FileName const oldFile(owner_->absFileName());
|
||||
if (!oldFile.copyTo(newFile))
|
||||
return string();
|
||||
FileName path(oldFile.onlyPath());
|
||||
string relFile(to_utf8(newFile.relPath(path.absFileName())));
|
||||
string cmd("cvs -q add -m \"" + msg + "\" " + quoteName(relFile));
|
||||
return doVCCommand(cmd, path) ? string() : "CVS: Proceeded";
|
||||
}
|
||||
|
||||
|
||||
void CVS::getDiff(OperationMode opmode, FileName const & tmpf)
|
||||
{
|
||||
doVCCommandWithOutput("cvs diff " + getTarget(opmode),
|
||||
@ -1097,14 +1160,18 @@ FileName const SVN::findFile(FileName const & file)
|
||||
|
||||
void SVN::scanMaster()
|
||||
{
|
||||
// vcstatus code is somewhat superflous, until we want
|
||||
// to implement read-only toggle for svn.
|
||||
vcstatus = NOLOCKING;
|
||||
if (checkLockMode()) {
|
||||
if (isLocked()) {
|
||||
vcstatus = LOCKED;
|
||||
} else {
|
||||
vcstatus = UNLOCKED;
|
||||
// vcstatus code other than UNVERSIONED is somewhat superflous,
|
||||
// until we want to implement read-only toggle for svn.
|
||||
FileName f = findFile(owner_->fileName());
|
||||
if (f.empty()) {
|
||||
vcstatus = UNVERSIONED;
|
||||
} else {
|
||||
vcstatus = NOLOCKING;
|
||||
if (checkLockMode()) {
|
||||
if (isLocked())
|
||||
vcstatus = LOCKED;
|
||||
else
|
||||
vcstatus = UNLOCKED;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1166,7 +1233,75 @@ void SVN::registrer(string const & /*msg*/)
|
||||
}
|
||||
|
||||
|
||||
bool SVN::renameEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
string SVN::rename(support::FileName const & newFile, string const & msg)
|
||||
{
|
||||
// svn move does not require a log message, since it does not commit.
|
||||
// In LyX we commit immediately afterwards, otherwise it could be
|
||||
// confusing to the user to have two uncommitted files.
|
||||
FileName path(owner_->filePath());
|
||||
string relFile(to_utf8(newFile.relPath(path.absFileName())));
|
||||
string cmd("svn move -q " + quoteName(onlyFileName(owner_->absFileName())) +
|
||||
' ' + quoteName(relFile));
|
||||
if (doVCCommand(cmd, path)) {
|
||||
cmd = "svn revert -q " +
|
||||
quoteName(onlyFileName(owner_->absFileName())) + ' ' +
|
||||
quoteName(relFile);
|
||||
doVCCommand(cmd, path);
|
||||
if (newFile.exists())
|
||||
newFile.removeFile();
|
||||
return string();
|
||||
}
|
||||
vector<support::FileName> f;
|
||||
f.push_back(owner_->fileName());
|
||||
f.push_back(newFile);
|
||||
string log;
|
||||
if (checkIn(f, msg, log) != LyXVC::Success) {
|
||||
cmd = "svn revert -q " +
|
||||
quoteName(onlyFileName(owner_->absFileName())) + ' ' +
|
||||
quoteName(relFile);
|
||||
doVCCommand(cmd, path);
|
||||
if (newFile.exists())
|
||||
newFile.removeFile();
|
||||
return string();
|
||||
}
|
||||
return log;
|
||||
}
|
||||
|
||||
|
||||
string SVN::copy(support::FileName const & newFile, string const & msg)
|
||||
{
|
||||
// svn copy does not require a log message, since it does not commit.
|
||||
// In LyX we commit immediately afterwards, otherwise it could be
|
||||
// confusing to the user to have an uncommitted file.
|
||||
FileName path(owner_->filePath());
|
||||
string relFile(to_utf8(newFile.relPath(path.absFileName())));
|
||||
string cmd("svn copy -q " + quoteName(onlyFileName(owner_->absFileName())) +
|
||||
' ' + quoteName(relFile));
|
||||
if (doVCCommand(cmd, path))
|
||||
return string();
|
||||
vector<support::FileName> f(1, newFile);
|
||||
string log;
|
||||
if (checkIn(f, msg, log) == LyXVC::Success)
|
||||
return log;
|
||||
return string();
|
||||
}
|
||||
|
||||
|
||||
LyXVC::CommandResult SVN::checkIn(string const & msg, string & log)
|
||||
{
|
||||
vector<support::FileName> f(1, owner_->fileName());
|
||||
return checkIn(f, msg, log);
|
||||
}
|
||||
|
||||
|
||||
LyXVC::CommandResult
|
||||
SVN::checkIn(vector<support::FileName> const & f, string const & msg, string & log)
|
||||
{
|
||||
FileName tmpf = FileName::tempName("lyxvcout");
|
||||
if (tmpf.empty()){
|
||||
@ -1177,7 +1312,8 @@ LyXVC::CommandResult SVN::checkIn(string const & msg, string & log)
|
||||
|
||||
ostringstream os;
|
||||
os << "svn commit -m \"" << msg << '"';
|
||||
os << ' ' << quoteName(onlyFileName(owner_->absFileName()));
|
||||
for (size_t i = 0; i < f.size(); ++i)
|
||||
os << ' ' << quoteName(f[i].onlyFileName());
|
||||
os << " > " << quoteName(tmpf.toFilesystemEncoding());
|
||||
LyXVC::CommandResult ret =
|
||||
doVCCommand(os.str(), FileName(owner_->filePath())) ?
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "support/FileName.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "LyXVC.h"
|
||||
|
||||
@ -31,7 +32,10 @@ public:
|
||||
enum VCStatus {
|
||||
UNLOCKED,
|
||||
LOCKED,
|
||||
NOLOCKING
|
||||
NOLOCKING,
|
||||
/// This file is not in version control, but it could be aded
|
||||
/// (because the path is under version control)
|
||||
UNVERSIONED,
|
||||
};
|
||||
|
||||
VCS(Buffer * b) : owner_(b) {}
|
||||
@ -39,6 +43,12 @@ public:
|
||||
|
||||
/// register a file for version control
|
||||
virtual void registrer(std::string const & msg) = 0;
|
||||
/// can this operation be processed in the current VCS?
|
||||
virtual bool renameEnabled() = 0;
|
||||
/// rename a file. Return non-empty log on success, empty log on failure.
|
||||
virtual std::string rename(support::FileName const &, std::string const &) = 0;
|
||||
/// copy a file. Return non-empty log on success, empty log on failure.
|
||||
virtual std::string copy(support::FileName const &, std::string const &) = 0;
|
||||
/// check in the current revision.
|
||||
/// \p log is non-empty on success and may be empty on failure.
|
||||
virtual LyXVC::CommandResult
|
||||
@ -142,6 +152,12 @@ public:
|
||||
|
||||
virtual void registrer(std::string const & msg);
|
||||
|
||||
virtual bool renameEnabled();
|
||||
|
||||
virtual std::string rename(support::FileName const &, std::string const &);
|
||||
|
||||
virtual std::string copy(support::FileName const &, std::string const &);
|
||||
|
||||
virtual LyXVC::CommandResult
|
||||
checkIn(std::string const & msg, std::string & log);
|
||||
|
||||
@ -217,6 +233,12 @@ public:
|
||||
|
||||
virtual void registrer(std::string const & msg);
|
||||
|
||||
virtual bool renameEnabled();
|
||||
|
||||
virtual std::string rename(support::FileName const &, std::string const &);
|
||||
|
||||
virtual std::string copy(support::FileName const &, std::string const &);
|
||||
|
||||
virtual LyXVC::CommandResult
|
||||
checkIn(std::string const & msg, std::string & log);
|
||||
|
||||
@ -347,6 +369,12 @@ public:
|
||||
|
||||
virtual void registrer(std::string const & msg);
|
||||
|
||||
virtual bool renameEnabled();
|
||||
|
||||
virtual std::string rename(support::FileName const &, std::string const &);
|
||||
|
||||
virtual std::string copy(support::FileName const &, std::string const &);
|
||||
|
||||
virtual LyXVC::CommandResult
|
||||
checkIn(std::string const & msg, std::string & log);
|
||||
|
||||
@ -398,6 +426,9 @@ protected:
|
||||
bool isLocked() const;
|
||||
/// acquire/release write lock for the current file
|
||||
bool fileLock(bool lock, support::FileName const & tmpf, std::string & status);
|
||||
/// Check in files \p f with log \p msg
|
||||
LyXVC::CommandResult checkIn(std::vector<support::FileName> const & f,
|
||||
std::string const & msg, std::string & log);
|
||||
|
||||
private:
|
||||
/// is the loaded file under locking policy?
|
||||
|
@ -1804,6 +1804,12 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
|
||||
case LFUN_VC_REGISTER:
|
||||
enable = doc_buffer && !doc_buffer->lyxvc().inUse();
|
||||
break;
|
||||
case LFUN_VC_RENAME:
|
||||
enable = doc_buffer && doc_buffer->lyxvc().renameEnabled();
|
||||
break;
|
||||
case LFUN_VC_COPY:
|
||||
enable = doc_buffer && doc_buffer->lyxvc().copyEnabled();
|
||||
break;
|
||||
case LFUN_VC_CHECK_IN:
|
||||
enable = doc_buffer && doc_buffer->lyxvc().checkInEnabled();
|
||||
break;
|
||||
@ -2209,7 +2215,7 @@ void GuiView::insertLyXFile(docstring const & fname)
|
||||
}
|
||||
|
||||
|
||||
bool GuiView::renameBuffer(Buffer & b, docstring const & newname)
|
||||
bool GuiView::renameBuffer(Buffer & b, docstring const & newname, RenameKind kind)
|
||||
{
|
||||
FileName fname = b.fileName();
|
||||
FileName const oldname = fname;
|
||||
@ -2263,27 +2269,74 @@ bool GuiView::renameBuffer(Buffer & b, docstring const & newname)
|
||||
int const ret = Alert::prompt(_("Chosen File Already Open"),
|
||||
text, 0, 1, _("&Rename"), _("&Cancel"));
|
||||
switch (ret) {
|
||||
case 0: return renameBuffer(b, docstring());
|
||||
case 0: return renameBuffer(b, docstring(), kind);
|
||||
case 1: return false;
|
||||
}
|
||||
//return false;
|
||||
}
|
||||
|
||||
if (FileName(fname).exists()) {
|
||||
|
||||
bool const existsLocal = fname.exists();
|
||||
bool const existsInVC = LyXVC::fileInVC(fname);
|
||||
if (existsLocal || existsInVC) {
|
||||
docstring const file = makeDisplayPath(fname.absFileName(), 30);
|
||||
docstring const text = bformat(_("The document %1$s already "
|
||||
"exists.\n\nDo you want to "
|
||||
"overwrite that document?"),
|
||||
file);
|
||||
int const ret = Alert::prompt(_("Overwrite document?"),
|
||||
text, 0, 2, _("&Overwrite"), _("&Rename"), _("&Cancel"));
|
||||
switch (ret) {
|
||||
case 0: break;
|
||||
case 1: return renameBuffer(b, docstring());
|
||||
case 2: return false;
|
||||
if (kind != LV_WRITE_AS && existsInVC) {
|
||||
// renaming to a name that is already in VC
|
||||
// would not work
|
||||
docstring text = bformat(_("The document %1$s "
|
||||
"is already registered.\n\n"
|
||||
"Do you want to choose a new name?"),
|
||||
file);
|
||||
docstring const title = (kind == LV_VC_RENAME) ?
|
||||
_("Rename document?") : _("Copy document?");
|
||||
docstring const button = (kind == LV_VC_RENAME) ?
|
||||
_("&Rename") : _("&Copy");
|
||||
int const ret = Alert::prompt(title, text, 0, 1,
|
||||
button, _("&Cancel"));
|
||||
switch (ret) {
|
||||
case 0: return renameBuffer(b, docstring(), kind);
|
||||
case 1: return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (existsLocal) {
|
||||
docstring text = bformat(_("The document %1$s "
|
||||
"already exists.\n\n"
|
||||
"Do you want to overwrite that document?"),
|
||||
file);
|
||||
int const ret = Alert::prompt(_("Overwrite document?"),
|
||||
text, 0, 2, _("&Overwrite"),
|
||||
_("&Rename"), _("&Cancel"));
|
||||
switch (ret) {
|
||||
case 0: break;
|
||||
case 1: return renameBuffer(b, docstring(), kind);
|
||||
case 2: return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (kind) {
|
||||
case LV_VC_RENAME: {
|
||||
string msg = b.lyxvc().rename(fname);
|
||||
if (msg.empty())
|
||||
return false;
|
||||
message(from_utf8(msg));
|
||||
break;
|
||||
}
|
||||
case LV_VC_COPY: {
|
||||
string msg = b.lyxvc().copy(fname);
|
||||
if (msg.empty())
|
||||
return false;
|
||||
message(from_utf8(msg));
|
||||
break;
|
||||
}
|
||||
case LV_WRITE_AS:
|
||||
break;
|
||||
}
|
||||
// LyXVC created the file already in case of LV_VC_RENAME or
|
||||
// LV_VC_COPY, but call saveBuffer() nevertheless to get
|
||||
// relative paths of included stuff right if we moved e.g. from
|
||||
// /a/b.lyx to /a/c/b.lyx.
|
||||
|
||||
bool const saved = saveBuffer(b, fname);
|
||||
if (saved)
|
||||
b.reload(false);
|
||||
@ -2412,7 +2465,7 @@ bool GuiView::saveBuffer(Buffer & b, FileName const & fn)
|
||||
return false;
|
||||
}
|
||||
|
||||
return saveBuffer(b);
|
||||
return saveBuffer(b, fn);
|
||||
}
|
||||
|
||||
|
||||
@ -2809,6 +2862,36 @@ void GuiView::dispatchVC(FuncRequest const & cmd, DispatchResult & dr)
|
||||
}
|
||||
break;
|
||||
|
||||
case LFUN_VC_RENAME:
|
||||
case LFUN_VC_COPY: {
|
||||
if (!buffer || !ensureBufferClean(buffer))
|
||||
break;
|
||||
if (buffer->lyxvc().inUse() && !buffer->isReadonly()) {
|
||||
if (buffer->lyxvc().isCheckInWithConfirmation()) {
|
||||
// Some changes are not yet committed.
|
||||
// We test here and not in getStatus(), since
|
||||
// this test is expensive.
|
||||
string log;
|
||||
LyXVC::CommandResult ret =
|
||||
buffer->lyxvc().checkIn(log);
|
||||
dr.setMessage(log);
|
||||
if (ret == LyXVC::ErrorCommand ||
|
||||
ret == LyXVC::Success)
|
||||
reloadBuffer(*buffer);
|
||||
if (buffer->lyxvc().isCheckInWithConfirmation()) {
|
||||
frontend::Alert::error(
|
||||
_("Revision control error."),
|
||||
_("Document could not be checked in."));
|
||||
break;
|
||||
}
|
||||
}
|
||||
RenameKind const kind = (cmd.action() == LFUN_VC_RENAME) ?
|
||||
LV_VC_RENAME : LV_VC_COPY;
|
||||
renameBuffer(*buffer, cmd.argument(), kind);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case LFUN_VC_CHECK_IN:
|
||||
if (!buffer || !ensureBufferClean(buffer))
|
||||
break;
|
||||
@ -3606,6 +3689,8 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
|
||||
break;
|
||||
|
||||
case LFUN_VC_REGISTER:
|
||||
case LFUN_VC_RENAME:
|
||||
case LFUN_VC_COPY:
|
||||
case LFUN_VC_CHECK_IN:
|
||||
case LFUN_VC_CHECK_OUT:
|
||||
case LFUN_VC_REPO_UPDATE:
|
||||
|
@ -355,6 +355,8 @@ private:
|
||||
///
|
||||
bool exportBufferAs(Buffer & b);
|
||||
|
||||
///
|
||||
enum RenameKind { LV_WRITE_AS, LV_VC_RENAME, LV_VC_COPY };
|
||||
/// Save a buffer as a new file.
|
||||
/**
|
||||
Write a buffer to a new file name and rename the buffer
|
||||
@ -369,8 +371,14 @@ private:
|
||||
If 'newname' is non-empty and has an absolute path, that is used.
|
||||
Otherwise the base directory of the buffer is used as the base
|
||||
for any relative path in 'newname'.
|
||||
*/
|
||||
bool renameBuffer(Buffer & b, docstring const & newname);
|
||||
|
||||
\p kind controls what is done besides the pure renaming:
|
||||
* LV_WRITE_AS => The buffer is written without version control actions.
|
||||
* LV_VC_RENAME => The file is renamed in version control.
|
||||
* LV_VC_COPY => The file is copied in version control.
|
||||
*/
|
||||
bool renameBuffer(Buffer & b, docstring const & newname,
|
||||
RenameKind kind = LV_WRITE_AS);
|
||||
///
|
||||
bool saveBuffer(Buffer & b);
|
||||
/// save and rename buffer to fn. If fn is empty, the buffer
|
||||
|
Loading…
Reference in New Issue
Block a user