Support for multiple custom actions

FossilOrigin-Name: 172938d454db50a53cd0e0435991a7fccea59ae7
This commit is contained in:
kostas 2015-07-09 18:55:33 +00:00
parent 2429d6ca9e
commit 78276623a4
10 changed files with 422 additions and 145 deletions

View File

@ -1,5 +1,5 @@
C Initial\swork\son\suser\sdefined\sfile\sactions\n
D 2015-06-02T17:28:10.948
C Support\sfor\smultiple\scustom\sactions\n
D 2015-07-09T18:55:33.249
F .travis.yml 77966888a81c4ceee1fcc79bce842c9667ad8a35
F debian/changelog eb4304dfcb6bb66850ec740838090eb50ce1249b
F debian/compat b6abd567fa79cbe0196d093a067271361dc6ca8b
@ -224,18 +224,18 @@ F src/FslSettingsDialog.cpp 2531d3709f0eab66651671e3edead2ca720d07d5
F src/FslSettingsDialog.h dfe2a61884a55a74cbb9206b6f6b482b979725e7
F src/LoggedProcess.cpp 2a1e5c94bc1e57c8984563e66c210e43a14dc60c
F src/LoggedProcess.h 85df7c635c807a5a0e8c4763f17a0752aaff7261
F src/MainWindow.cpp 8521536cfe2167d5b82bc5c7808dff8117d3da4f
F src/MainWindow.h d3216b30702df9a44b3a93e6c96fd05ceb0e3822
F src/MainWindow.cpp 272e8424e81eb81b1c7a996ded26a217f9ec45e5
F src/MainWindow.h b03f3d99985dd6d2bfe406239ca54e69f571db6a
F src/RemoteDialog.cpp 8540cc5e2e41c4127ed8a028d84691604fa6ecac
F src/RemoteDialog.h 5e0438c2bd7c79b1bb44bfbd58c2181b544a9e5d
F src/RevisionDialog.cpp e58c4f8a704f00addebb15d521b76620fdafda79
F src/RevisionDialog.h b718c3009342eaabad39c8a11a253a4e4fef7a73
F src/SearchBox.cpp d4209c575baa9933e1ce5ed376e785b289a145ba
F src/SearchBox.h 0c78d3a68136dab3e0e71b83ae36f22bd2688ab2
F src/Settings.cpp 8e8c85f2c2aecb6df3d456ce775a4a53704ebbed
F src/Settings.h 9eeeec1ac9cee4d8dc44a448995d0d599274c2ff
F src/SettingsDialog.cpp 611405e28ce746b2db6ff210c2784d5b8f2dbde8
F src/SettingsDialog.h fea64d7f92ff326ea49f14559e36379892c0a7c4
F src/Settings.cpp 258d3f466f6a125ce2b8519d6d57a312cbc44a3f
F src/Settings.h 02bee6bd1178dc456fc80b277edd0843e535649c
F src/SettingsDialog.cpp b0d0bfc45534b7bed148776d4c3865a68d59ec15
F src/SettingsDialog.h 5eb3ae2cbb00ab5544e1889860f5376f69fe47cd
F src/Utils.cpp d53b1b92352e586a7c12a19ec6b109a9f095b7f1
F src/Utils.h 011e4be3f94cd26be537299cd44ab9c135db44a5
F src/Workspace.cpp 7004c2c30f79d2e64691aa9b2c55ee72a84d978b
@ -248,14 +248,11 @@ F ui/CloneDialog.ui 4886e7d4f258ea8b852b5eefc860396e35145712
F ui/CommitDialog.ui 1e5dafa742e9ae07ec937bcda8cda3297ddc6199
F ui/FileActionDialog.ui 89bb4dc2d0b8adcd41adcb11ec65f2028a09a12d
F ui/FslSettingsDialog.ui eb3d4cb764cab90b01e82922237d8c42d6ce1749
F ui/MainWindow.ui 140d5b3e8c37d2e764afd3ee9e74bc754888d067
F ui/MainWindow.ui 10181826a25056ed5aba2b23a7d110159be7c043
F ui/RemoteDialog.ui 95a4750d972ed8c49bb10b95db91ff16cfe2dd0b
F ui/RevisionDialog.ui 27c3b98c665fec014a50cbf3352c0627f75e68cd
F ui/SettingsDialog.ui 2a84288694c666badb6f29e4badaa3f0bdd46287
P 1954aea71218df9a36b6059fac19ab416ef470dc
R e725cdba0f62a2aad3ff979a23275b03
T *branch * user-actions
T *sym-user-actions *
T -sym-trunk *
F ui/SettingsDialog.ui b5858067cdb16c3f132af4cf8332e4ad255c915c
P c1562dbda3ad33559227bb0d2fd177e35cae6681
R 084d6ff50c0d7d634da28bd5e41e98ef
U kostas
Z 732d3b0fa352093eb465015746a344aa
Z 5e0824e216c8fc6ae7795004bb7a7ace

View File

@ -1 +1 @@
c1562dbda3ad33559227bb0d2fd177e35cae6681
172938d454db50a53cd0e0435991a7fccea59ae7

View File

@ -99,6 +99,12 @@ MainWindow::MainWindow(Settings &_settings, QWidget *parent, QString *workspaceP
QAction *separator = new QAction(this);
separator->setSeparator(true);
fileActionSeparator = new QAction(this);
fileActionSeparator->setSeparator(true);
workspaceActionSeparator = new QAction(this);
workspaceActionSeparator->setSeparator(true);
// fileTableView
ui->fileTableView->setModel(&getWorkspace().getFileModel());
@ -106,8 +112,6 @@ MainWindow::MainWindow(Settings &_settings, QWidget *parent, QString *workspaceP
ui->fileTableView->addAction(ui->actionHistory);
ui->fileTableView->addAction(ui->actionOpenFile);
ui->fileTableView->addAction(ui->actionOpenContaining);
ui->actionCustomFileAction->setVisible(false);
ui->fileTableView->addAction(ui->actionCustomFileAction);
ui->fileTableView->addAction(separator);
ui->fileTableView->addAction(ui->actionAdd);
ui->fileTableView->addAction(ui->actionRevert);
@ -202,7 +206,7 @@ MainWindow::MainWindow(Settings &_settings, QWidget *parent, QString *workspaceP
}
}
Q_ASSERT(recent_sep);
for (int i = 0; i < MAX_RECENT; ++i)
for(int i = 0; i < MAX_RECENT; ++i)
{
recentWorkspaceActs[i] = new QAction(this);
recentWorkspaceActs[i]->setVisible(false);
@ -210,6 +214,17 @@ MainWindow::MainWindow(Settings &_settings, QWidget *parent, QString *workspaceP
ui->menuFile->insertAction(recent_sep, recentWorkspaceActs[i]);
}
// Custom Actions
//ui->fileTableView->addAction(separator);
for(int i = 0; i < settings.GetCustomActions().size(); ++i)
{
customActions[i] = new QAction(this);
customActions[i]->setVisible(false);
connect(customActions[i], SIGNAL(triggered()), this, SLOT(on_actionCustomAction_triggered()));
customActions[i]->setData(i);
customActions[i]->setShortcut(QKeySequence(QString("Ctrl+%0").arg(i+1)));
}
// TabWidget
ui->tabWidget->setCurrentIndex(TAB_LOG);
@ -608,7 +623,6 @@ void MainWindow::enableActions(bool on)
ui->actionCreateBranch,
ui->actionMergeBranch,
ui->actionFossilSettings,
ui->actionCustomFileAction
};
for(size_t i=0; i<COUNTOF(actions); ++i)
@ -1060,6 +1074,35 @@ void MainWindow::applySettings()
if(!active_workspace.isEmpty())
setCurrentWorkspace(active_workspace);
// Custom Actions
for(int i=0; i<MAX_CUSTOM_ACTIONS; ++i)
settings.GetCustomActions()[i].Clear();
int num_actions = store->beginReadArray("CustomActions");
int last_action = 0;
for(int i=0; i<num_actions; ++i)
{
store->setArrayIndex(i);
CustomAction &action = settings.GetCustomActions()[last_action];
QString descr;
if(store->contains("Description"))
descr = store->value("Description").toString();
if(descr.isEmpty())
continue;
action.Description = descr;
if(store->contains("Command"))
action.Command = store->value("Command").toString();
if(store->contains("Context"))
action.Context = static_cast<CustomActionContext>(store->value("Context").toInt());
++last_action;
}
store->endArray();
applyUserActions();
}
@ -1099,6 +1142,24 @@ void MainWindow::updateSettings()
store->setValue("ViewUnchanged", ui->actionViewUnchanged->isChecked());
store->setValue("ViewIgnored", ui->actionViewIgnored->isChecked());
store->setValue("ViewAsList", ui->actionViewAsList->isChecked());
// Custom Actions
Settings::custom_actions_t &actions = settings.GetCustomActions();
store->beginWriteArray("CustomActions", actions.size());
int active_actions = 0;
for(int i=0; i<actions.size(); ++i)
{
CustomAction &action = actions[i];
if(!action.IsValid())
continue;
store->setArrayIndex(active_actions);
store->setValue("Description", action.Description);
store->setValue("Command", action.Command);
store->setValue("Context", static_cast<int>(action.Context));
++active_actions;
}
store->endArray();
}
//------------------------------------------------------------------------------
@ -2672,42 +2733,128 @@ void MainWindow::on_actionDeleteRemote_triggered()
//------------------------------------------------------------------------------
void MainWindow::applyUserActions()
{
QString fileaction_name;
QString fileaction_cmd;
Settings::custom_actions_t custom_actions = settings.GetCustomActions();
Q_ASSERT(MAX_CUSTOM_ACTIONS == custom_actions.size());
if(settings.HasValue(FUEL_SETTING_FILEACTION_NAME) && settings.HasValue(FUEL_SETTING_FILEACTION_COMMAND))
// Remove All Actions
for(int i = 0; i < custom_actions.size(); ++i)
{
fileaction_name = settings.GetValue(FUEL_SETTING_FILEACTION_NAME).toString();
fileaction_cmd = settings.GetValue(FUEL_SETTING_FILEACTION_COMMAND).toString();
QAction *action = customActions[i];
ui->fileTableView->removeAction(action);
menuWorkspace->removeAction(action);
}
ui->fileTableView->removeAction(fileActionSeparator);
menuWorkspace->removeAction(workspaceActionSeparator);
// Add them to the top
ui->fileTableView->addAction(fileActionSeparator);
menuWorkspace->addAction(workspaceActionSeparator);
bool has_file_actions = false;
bool has_folder_actions = false;
for(int i = 0; i < custom_actions.size(); ++i)
{
CustomAction &cust_act = custom_actions[i];
QAction *action = customActions[i];
action->setVisible(cust_act.IsValid());
action->setText(cust_act.Description);
if(cust_act.IsActive(ACTION_CONTEXT_FILES))
{
ui->fileTableView->addAction(action);
has_file_actions = true;
}
if(cust_act.IsActive(ACTION_CONTEXT_FOLDERS))
{
menuWorkspace->addAction(action);
has_folder_actions = true;
}
}
if(!fileaction_name.isEmpty() && !fileaction_cmd.isEmpty())
{
ui->actionCustomFileAction->setVisible(true);
ui->actionCustomFileAction->setText(fileaction_name);
}
else
ui->actionCustomFileAction->setVisible(false);
if(!has_file_actions)
ui->fileTableView->removeAction(fileActionSeparator);
if(!has_folder_actions)
menuWorkspace->removeAction(workspaceActionSeparator);
}
//------------------------------------------------------------------------------
void MainWindow::on_actionCustomFileAction_triggered()
void MainWindow::on_actionCustomAction_triggered()
{
if(!settings.HasValue(FUEL_SETTING_FILEACTION_NAME) || !settings.HasValue(FUEL_SETTING_FILEACTION_COMMAND))
QAction *action = qobject_cast<QAction *>(sender());
if(!action)
return;
QStringList selection;
getSelectionFilenames(selection, WorkspaceFile::TYPE_ALL);
QProcess proc(this);
int action_id = action->data().toInt();
Q_ASSERT(action_id < settings.GetCustomActions().size());
CustomAction &cust_action = settings.GetCustomActions()[action_id];
Q_ASSERT(cust_action.IsValid());
QStringList params;
foreach(const QString &f, selection)
// Process command string
QString cmd = cust_action.Command;
Q_ASSERT(!cmd.isEmpty());
// Split command from embedded params
QString extra_params;
// Command ends after first space
QChar cmd_char_end = ' ';
int start = 0 ;
// Unless it is a quoted command
if(cmd[0]=='"')
{
QString path = QFileInfo(fossil().getCurrentWorkspace() + "/" + f).absoluteFilePath();
params.append(path);
cmd_char_end = '"';
start = 1;
}
const QString &cmd = settings.GetValue(FUEL_SETTING_FILEACTION_COMMAND).toString();
int cmd_end = cmd.indexOf(cmd_char_end, start);
if(cmd_end != -1)
{
extra_params = cmd.mid(cmd_end+1);
cmd = cmd.left(cmd_end);
}
cmd = cmd.trimmed();
extra_params = extra_params.trimmed();
QStringList extra_param_list = extra_params.split(' ');
foreach(const QString &p, extra_param_list)
params.push_back(p);
// Extract selection
if(cust_action.IsActive(ACTION_CONTEXT_FILES))
{
QStringList file_selection;
getSelectionFilenames(file_selection, WorkspaceFile::TYPE_ALL);
foreach(const QString &f, file_selection)
{
QString path = QFileInfo(fossil().getCurrentWorkspace() + "/" + f).absoluteFilePath();
params.append(path);
}
}
if(cust_action.IsActive(ACTION_CONTEXT_FOLDERS))
{
stringset_t path_selection;
getSelectionPaths(path_selection);
foreach(const QString &f, path_selection)
{
QString path = QFileInfo(fossil().getCurrentWorkspace() + "/" + f).absoluteFilePath();
params.append(path);
}
}
// Skip action if nothing is available
if(params.empty())
return;
log("<b>"+cmd + " "+params.join(" ")+"</b><br>", true);
QProcess proc(this);
proc.startDetached(cmd, params);
}
}

View File

@ -134,7 +134,7 @@ private slots:
void on_actionSetDefaultRemote_triggered();
void on_actionAddRemote_triggered();
void on_actionDeleteRemote_triggered();
void on_actionCustomFileAction_triggered();
void on_actionCustomAction_triggered();
private:
class MainWinUICallback : public UICallback
@ -172,6 +172,9 @@ private:
QFileIconProvider iconProvider;
icon_map_t iconCache;
class QAction *recentWorkspaceActs[MAX_RECENT];
class QAction *customActions[MAX_CUSTOM_ACTIONS];
class QAction *fileActionSeparator;
class QAction *workspaceActionSeparator;
class QProgressBar *progressBar;
class QLabel *lblRevision;
class QLabel *lblTags;

View File

@ -37,10 +37,13 @@ Settings::Settings(bool portableMode) : store(0)
if(!HasValue(FUEL_SETTING_WEB_BROWSER))
SetValue(FUEL_SETTING_WEB_BROWSER, 0);
if(!HasValue(FUEL_SETTING_FILEACTION_NAME))
SetValue(FUEL_SETTING_FILEACTION_NAME, "");
if(!HasValue(FUEL_SETTING_FILEACTION_COMMAND))
SetValue(FUEL_SETTING_FILEACTION_COMMAND, "");
for(int i=0; i<MAX_CUSTOM_ACTIONS; ++i)
{
CustomAction action;
action.Id = QObject::tr("Custom Action %0").arg(i+1);
customActions.append(action);
}
ApplyEnvironment();
}

View File

@ -4,14 +4,13 @@
#include <QMap>
#include <QVariant>
#include <QTranslator>
#include <QVector>
#define FUEL_SETTING_FOSSIL_PATH "FossilPath"
#define FUEL_SETTING_COMMIT_MSG "CommitMsgHistory"
#define FUEL_SETTING_FILE_DBLCLICK "FileDblClickAction"
#define FUEL_SETTING_LANGUAGE "Language"
#define FUEL_SETTING_WEB_BROWSER "WebBrowser"
#define FUEL_SETTING_FILEACTION_NAME "FileActionName"
#define FUEL_SETTING_FILEACTION_COMMAND "FileActionCommand"
#define FOSSIL_SETTING_GDIFF_CMD "gdiff-command"
#define FOSSIL_SETTING_GMERGE_CMD "gmerge-command"
@ -29,6 +28,50 @@ enum FileDblClickAction
FILE_DLBCLICK_ACTION_MAX
};
enum CustomActionContext
{
ACTION_CONTEXT_FILES = 1 << 0,
ACTION_CONTEXT_FOLDERS = 1 << 1,
ACTION_CONTEXT_FILES_AND_FOLDERS = ACTION_CONTEXT_FILES|ACTION_CONTEXT_FOLDERS
};
enum
{
MAX_CUSTOM_ACTIONS = 5
};
struct CustomAction
{
QString Id;
QString Description;
QString Command;
CustomActionContext Context;
CustomAction()
{
Clear();
}
bool IsValid() const
{
return !(Description.isEmpty() || Command.isEmpty());
}
bool IsActive(CustomActionContext context) const
{
return (Context & context) != 0;
}
void Clear()
{
Description.clear();
Command.clear();
Context = ACTION_CONTEXT_FILES;
}
};
struct Settings
{
struct Setting
@ -45,6 +88,7 @@ struct Settings
SettingType Type;
};
typedef QMap<QString, Setting> mappings_t;
typedef QVector<CustomAction> custom_actions_t;
Settings(bool portableMode = false);
@ -65,10 +109,14 @@ struct Settings
bool SupportsLang(const QString &langId) const;
bool InstallLang(const QString &langId);
custom_actions_t &GetCustomActions() { return customActions; }
private:
mappings_t Mappings;
class QSettings *store;
QTranslator translator;
mappings_t Mappings;
class QSettings *store;
QTranslator translator;
custom_actions_t customActions;
};

View File

@ -26,9 +26,6 @@ SettingsDialog::SettingsDialog(QWidget *parent, Settings &_settings) :
ui->cmbDoubleClickAction->setCurrentIndex(settings->GetValue(FUEL_SETTING_FILE_DBLCLICK).toInt());
ui->cmbFossilBrowser->setCurrentIndex(settings->GetValue(FUEL_SETTING_WEB_BROWSER).toInt());
ui->lineCustomFileActionName->setText(settings->GetValue(FUEL_SETTING_FILEACTION_NAME).toString());
ui->lineCustomFileActionCommand->setText(settings->GetValue(FUEL_SETTING_FILEACTION_COMMAND).toString());
// Initialize language combo
foreach(const LangMap &m, langMap)
ui->cmbActiveLanguage->addItem(m.name);
@ -39,6 +36,22 @@ SettingsDialog::SettingsDialog(QWidget *parent, Settings &_settings) :
ui->cmbActiveLanguage->findText(
LangIdToName(lang)));
lastActionIndex = 0;
currentCustomActions = settings->GetCustomActions();
ui->cmbCustomActionContext->addItem(tr("Files"));
ui->cmbCustomActionContext->addItem(tr("Folders"));
ui->cmbCustomActionContext->setCurrentIndex(0);
GetCustomAction(0);
for(int i=0; i<currentCustomActions.size(); ++i)
{
CustomAction &a = currentCustomActions[i];
ui->cmbCustomAction->addItem(a.Id);
}
ui->cmbCustomAction->setCurrentIndex(0);
}
//-----------------------------------------------------------------------------
@ -71,11 +84,16 @@ void SettingsDialog::on_buttonBox_accepted()
if(curr_langid != new_langid)
QMessageBox::information(this, tr("Restart required"), tr("The language change will take effect after restarting the application"), QMessageBox::Ok);
for(int i=0; i<currentCustomActions.size(); ++i)
{
CustomAction &a = currentCustomActions[i];
a.Description = a.Description.trimmed();
a.Command = QDir::fromNativeSeparators(a.Command.trimmed());
}
Q_ASSERT(settings->HasValue(FUEL_SETTING_FILEACTION_NAME));
settings->SetValue(FUEL_SETTING_FILEACTION_NAME, ui->lineCustomFileActionName->text().trimmed());
Q_ASSERT(settings->HasValue(FUEL_SETTING_FILEACTION_COMMAND));
settings->SetValue(FUEL_SETTING_FILEACTION_COMMAND, QDir::fromNativeSeparators(ui->lineCustomFileActionCommand->text().trimmed()));
PutCustomAction(ui->cmbCustomAction->currentIndex());
settings->GetCustomActions() = currentCustomActions;
settings->ApplyEnvironment();
}
@ -134,7 +152,47 @@ QString SettingsDialog::LangNameToId(const QString &name)
//-----------------------------------------------------------------------------
void SettingsDialog::on_btnSelectCustomFileActionCommand_clicked()
{
QString path = SelectExe(this, tr("Select executable"));
QString path = SelectExe(this, tr("Select command"));
if(!path.isEmpty())
ui->lineCustomFileActionCommand->setText(QDir::toNativeSeparators(path));
ui->lineCustomActionCommand->setText(QDir::toNativeSeparators(path));
}
//-----------------------------------------------------------------------------
void SettingsDialog::GetCustomAction(int index)
{
Q_ASSERT(index>=0 && index < currentCustomActions.size());
CustomAction &action = currentCustomActions[index];
ui->lineCustomActionDescription->setText(action.Description);
ui->lineCustomActionCommand->setText(action.Command);
ui->cmbCustomActionContext->setCurrentIndex(action.Context-1);
}
//-----------------------------------------------------------------------------
void SettingsDialog::PutCustomAction(int index)
{
Q_ASSERT(index>=0 && index < currentCustomActions.size());
CustomAction &action = currentCustomActions[index];
action.Description = ui->lineCustomActionDescription->text().trimmed();
action.Command = QDir::fromNativeSeparators(ui->lineCustomActionCommand->text().trimmed());
action.Context = static_cast<CustomActionContext>(ui->cmbCustomActionContext->currentIndex()+1);
}
//-----------------------------------------------------------------------------
void SettingsDialog::on_cmbCustomAction_currentIndexChanged(int index)
{
if(index != lastActionIndex)
PutCustomAction(lastActionIndex);
GetCustomAction(index);
lastActionIndex = index;
}
//-----------------------------------------------------------------------------
void SettingsDialog::on_cmbCustomActionContext_currentIndexChanged(int index)
{
int action_index = ui->cmbCustomAction->currentIndex();
if(action_index<0)
return;
Q_ASSERT(action_index>=0 && action_index < currentCustomActions.size());
currentCustomActions[action_index].Context = static_cast<CustomActionContext>(index+1);
}

View File

@ -24,11 +24,15 @@ private slots:
void on_buttonBox_accepted();
void on_btnClearMessageHistory_clicked();
void on_btnSelectCustomFileActionCommand_clicked();
void on_cmbCustomAction_currentIndexChanged(int index);
void on_cmbCustomActionContext_currentIndexChanged(int index);
private:
QString LangIdToName(const QString &id);
QString LangNameToId(const QString &name);
void CreateLangMap();
void GetCustomAction(int index);
void PutCustomAction(int index);
struct LangMap
{
@ -44,6 +48,8 @@ private:
QList<LangMap> langMap;
Ui::SettingsDialog *ui;
Settings *settings;
Settings::custom_actions_t currentCustomActions;
int lastActionIndex;
};
#endif // SETTINGSDIALOG_H

View File

@ -1047,14 +1047,6 @@
<string>Delete Remote</string>
</property>
</action>
<action name="actionCustomFileAction">
<property name="text">
<string>Custom File Action</string>
</property>
<property name="iconText">
<string>Custom File Action</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>

View File

@ -9,8 +9,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>457</width>
<height>278</height>
<width>449</width>
<height>408</height>
</rect>
</property>
<property name="windowTitle">
@ -27,18 +27,6 @@
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QFormLayout" name="formLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="minimumSize">
@ -180,69 +168,104 @@
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_2">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Custom File Action Name</string>
<item row="5" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Custom Actions</string>
</property>
<layout class="QFormLayout" name="formLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<item row="1" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Action</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="cmbCustomAction"/>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lineCustomActionDescription">
<property name="toolTip">
<string>Name of custom action</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Description</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Context</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="cmbCustomActionContext"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_3">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Command</string>
</property>
</widget>
</item>
<item row="4" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_10">
<item>
<widget class="QLineEdit" name="lineCustomActionCommand">
<property name="toolTip">
<string>Custom action command line</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnSelectCustomFileActionCommand">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="lineCustomFileActionName">
<property name="toolTip">
<string>Name of custom action</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_3">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Custom File Action Command</string>
</property>
</widget>
</item>
<item row="6" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_10">
<item>
<widget class="QLineEdit" name="lineCustomFileActionCommand">
<property name="toolTip">
<string>Custom action command line</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnSelectCustomFileActionCommand">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>