Add Duplicate button to Execute Macro dialog
With the Duplicate button a macro is duplicated with a new name, e.g. duplicate a macro named "MyMacro.FCMacro" and you get a new duplicate file named "MyMacro@001.FCMacro", but the user has opportunity to override the new name with a name of his own or to cancel the operation. Functionality is similar to already existing ability to create copies of the .FCStd file, only for macros, and this must be done manually for each new file. Will be useful to coders mostly. Expected use case could be to save a history of the macro periodically as changes are made or perhaps to duplicate the macro first, and then make changes to the duplicate, eventually replacing the original once satisfied with the changes. New code is based largely on existing code from rename operation, but with QFile.copy() instead of QFile.rename() used, along with other changes needed, such as generating the new suggested filenames. link to forum discussion and demonstration video: https://forum.freecadweb.org/viewtopic.php?f=8&p=254014&sid=98243801791920b69086a3fcd4699e34#p254014 Not sure how to make the Duplicate button label text translate when changing languages.
This commit is contained in:
committed by
Yorik van Havre
parent
299f68cda6
commit
43d16fc87a
@@ -166,9 +166,6 @@
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="mode" >
|
||||
<enum>Gui::FileChooser::Directory</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@@ -264,6 +261,16 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="duplicateButton">
|
||||
<property name="text">
|
||||
<string>Duplicate</string>
|
||||
</property>
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
@@ -309,9 +316,9 @@
|
||||
<tabstop>deleteButton</tabstop>
|
||||
<tabstop>editButton</tabstop>
|
||||
<tabstop>renameButton</tabstop>
|
||||
<tabstop>duplicateButton</tabstop>
|
||||
<tabstop>addonsButton</tabstop>
|
||||
<tabstop>fileChooser</tabstop>
|
||||
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
|
||||
@@ -139,6 +139,7 @@ void DlgMacroExecuteImp::on_userMacroListBox_currentItemChanged(QTreeWidgetItem*
|
||||
createButton->setEnabled(true);
|
||||
editButton->setEnabled(true);
|
||||
renameButton->setEnabled(true);
|
||||
duplicateButton->setEnabled(true);
|
||||
}
|
||||
else {
|
||||
executeButton->setEnabled(false);
|
||||
@@ -146,6 +147,7 @@ void DlgMacroExecuteImp::on_userMacroListBox_currentItemChanged(QTreeWidgetItem*
|
||||
createButton->setEnabled(true);
|
||||
editButton->setEnabled(false);
|
||||
renameButton->setEnabled(false);
|
||||
duplicateButton->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,6 +161,7 @@ void DlgMacroExecuteImp::on_systemMacroListBox_currentItemChanged(QTreeWidgetIte
|
||||
createButton->setEnabled(false);
|
||||
editButton->setEnabled(true); //look but don't touch
|
||||
renameButton->setEnabled(false);
|
||||
duplicateButton->setEnabled(false);
|
||||
}
|
||||
else {
|
||||
executeButton->setEnabled(false);
|
||||
@@ -166,6 +169,7 @@ void DlgMacroExecuteImp::on_systemMacroListBox_currentItemChanged(QTreeWidgetIte
|
||||
createButton->setEnabled(false);
|
||||
editButton->setEnabled(false);
|
||||
renameButton->setEnabled(false);
|
||||
duplicateButton->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,6 +185,7 @@ void DlgMacroExecuteImp::on_tabMacroWidget_currentChanged(int index)
|
||||
createButton->setEnabled(true);
|
||||
editButton->setEnabled(true);
|
||||
renameButton->setEnabled(true);
|
||||
duplicateButton->setEnabled(true);
|
||||
}
|
||||
else {
|
||||
executeButton->setEnabled(false);
|
||||
@@ -188,6 +193,7 @@ void DlgMacroExecuteImp::on_tabMacroWidget_currentChanged(int index)
|
||||
createButton->setEnabled(true);
|
||||
editButton->setEnabled(false);
|
||||
renameButton->setEnabled(false);
|
||||
duplicateButton->setEnabled(false);
|
||||
}
|
||||
}
|
||||
else { //index==1 system-wide
|
||||
@@ -199,6 +205,7 @@ void DlgMacroExecuteImp::on_tabMacroWidget_currentChanged(int index)
|
||||
createButton->setEnabled(false);
|
||||
editButton->setEnabled(true); //but you can't save it
|
||||
renameButton->setEnabled(false);
|
||||
duplicateButton->setEnabled(false);
|
||||
}
|
||||
else {
|
||||
executeButton->setEnabled(false);
|
||||
@@ -206,6 +213,7 @@ void DlgMacroExecuteImp::on_tabMacroWidget_currentChanged(int index)
|
||||
createButton->setEnabled(false);
|
||||
editButton->setEnabled(false);
|
||||
renameButton->setEnabled(false);
|
||||
duplicateButton->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -438,6 +446,93 @@ void DlgMacroExecuteImp::on_renameButton_clicked()
|
||||
}
|
||||
}
|
||||
}
|
||||
/**Duplicates selected macro
|
||||
* New file has same name as original but with "@" and 3-digit number appended
|
||||
* Begins with "@001" and increments until available name is found
|
||||
* "MyMacro.FCMacro" becomes "MyMacro@001.FCMacro"
|
||||
* "MyMacro@002.FCMacro.py" becomes "MyMacro@003.FCMacro.py" unless there is
|
||||
* no already existing "MyMacro@001.FCMacro.py"
|
||||
*/
|
||||
void DlgMacroExecuteImp::on_duplicateButton_clicked()
|
||||
{
|
||||
QDir dir;
|
||||
QTreeWidgetItem* item = 0;
|
||||
|
||||
int index = tabMacroWidget->currentIndex();
|
||||
if (index == 0) { //user-specific
|
||||
item = userMacroListBox->currentItem();
|
||||
dir.setPath(this->macroPath);
|
||||
}
|
||||
|
||||
if (!item){
|
||||
return;
|
||||
}
|
||||
|
||||
QString oldName = item->text(0);
|
||||
QFileInfo oldfi(dir, oldName);
|
||||
QFile oldfile(oldfi.absoluteFilePath());
|
||||
QString completeSuffix = oldfi.completeSuffix(); //everything after the first "."
|
||||
QString baseName = oldfi.baseName(); //everything before first "."
|
||||
QString neutralSymbol = QString::fromStdString("@");
|
||||
QString last3 = baseName.right(3);
|
||||
bool ok = true; //was conversion to int successful?
|
||||
int nLast3 = last3.toInt(&ok);
|
||||
last3 = QString::fromStdString("001"); //increment beginning with 001 no matter what
|
||||
if (ok ){
|
||||
//last3 were all digits, so we strip them from the base name
|
||||
if (baseName.size()>3){ //if <= 3 leave be (e.g. 2.py becomes 2@001.py)
|
||||
baseName = baseName.left(baseName.size()-3); //strip digits
|
||||
if (baseName.endsWith(neutralSymbol)){
|
||||
baseName = baseName.left(baseName.size()-1); //trim the "@", will be added back later
|
||||
}
|
||||
}
|
||||
}
|
||||
//at this point baseName = the base name without any digits, e.g. "MyMacro"
|
||||
//neutralSymbol = "@"
|
||||
//last3 is a string representing 3 digits, always "001" at this time
|
||||
//completeSuffix = FCMacro or py or FCMacro.py or else suffix will become FCMacro below
|
||||
|
||||
QString oldNameDigitized = baseName+neutralSymbol+last3+QString::fromStdString(".")+completeSuffix;
|
||||
QFileInfo fi(dir, oldNameDigitized);
|
||||
// increment until we find available name with smallest digits
|
||||
// test from "001" through "999", then give up and let user enter name of choice
|
||||
while (fi.exists()) {
|
||||
nLast3 = last3.toInt()+1;
|
||||
if (nLast3 >=1000){ //avoid infinite loop, 999 files will have to be enough
|
||||
break;
|
||||
}
|
||||
last3 = QString::number(nLast3);
|
||||
while (last3.size()<3){
|
||||
last3.prepend(QString::fromStdString("0")); //pad 0's if needed
|
||||
}
|
||||
oldNameDigitized = baseName+neutralSymbol+last3+QString::fromStdString(".")+completeSuffix;
|
||||
fi = QFileInfo(dir,oldNameDigitized);
|
||||
}
|
||||
|
||||
// give user a chance to pick a different name from digitized name suggested
|
||||
QString fn = QInputDialog::getText(this, tr("Duplicate Macro"),
|
||||
tr("Enter new name:"), QLineEdit::Normal, oldNameDigitized, 0);
|
||||
if (!fn.isEmpty() && fn != oldName) {
|
||||
QString suffix = QFileInfo(fn).suffix().toLower();
|
||||
if (suffix != QLatin1String("fcmacro") && suffix != QLatin1String("py")){
|
||||
fn += QLatin1String(".FCMacro");
|
||||
}
|
||||
QFileInfo fi(dir, fn);
|
||||
// check again if new name exists in case user changed it
|
||||
if (fi.exists()) {
|
||||
QMessageBox::warning(this, tr("Existing file"),
|
||||
tr("'%1'\n already exists.").arg(fi.absoluteFilePath()));
|
||||
}
|
||||
else if (!oldfile.copy(fi.absoluteFilePath())) {
|
||||
QMessageBox::warning(this, tr("Duplicate Failed"),
|
||||
tr("Failed to duplicate to '%1'.\nPerhaps a file permission error?").arg(fi.absoluteFilePath()));
|
||||
}
|
||||
|
||||
this->fillUpList(); //repopulate list to show new file
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* convenience link button to open tools -> addon manager
|
||||
* from within macro dialog
|
||||
|
||||
@@ -51,6 +51,7 @@ public Q_SLOTS:
|
||||
void on_deleteButton_clicked();
|
||||
void on_editButton_clicked();
|
||||
void on_renameButton_clicked();
|
||||
void on_duplicateButton_clicked();
|
||||
void on_addonsButton_clicked();
|
||||
|
||||
protected Q_SLOTS:
|
||||
|
||||
Reference in New Issue
Block a user