diff options
author | Muhammet Kara <muhammet.kara@collabora.com> | 2019-05-31 18:02:58 +0300 |
---|---|---|
committer | Muhammet Kara <muhammet.kara@collabora.com> | 2019-06-08 12:12:41 +0200 |
commit | fe977ec07087b103de8c809597fdaea8dd629837 (patch) | |
tree | ef2a358b5f3849207c240242298dbc46430b8847 | |
parent | 82bba7e4c044e54fc678ab108c662473d3a471a8 (diff) |
Auto redaction dialog second iteration
* Add the Add handler
* Add SfxAddTargetDialog dialog
* Add the Delete handler
Change-Id: I9c466754f6b593ffe3c8a1cc8034bbe47674f591
Reviewed-on: https://gerrit.libreoffice.org/73285
Tested-by: Jenkins
Reviewed-by: Muhammet Kara <muhammet.kara@collabora.com>
-rw-r--r-- | sfx2/UIConfig_sfx.mk | 1 | ||||
-rw-r--r-- | sfx2/inc/autoredactdialog.hxx (renamed from include/sfx2/autoredactdialog.hxx) | 54 | ||||
-rw-r--r-- | sfx2/source/doc/autoredactdialog.cxx | 190 | ||||
-rw-r--r-- | sfx2/source/doc/objserv.cxx | 2 | ||||
-rw-r--r-- | sfx2/uiconfig/ui/addtargetdialog.ui | 235 | ||||
-rw-r--r-- | sfx2/uiconfig/ui/autoredactdialog.ui | 10 |
6 files changed, 459 insertions, 33 deletions
diff --git a/sfx2/UIConfig_sfx.mk b/sfx2/UIConfig_sfx.mk index a7154213d128..0eb097b7fffd 100644 --- a/sfx2/UIConfig_sfx.mk +++ b/sfx2/UIConfig_sfx.mk @@ -11,6 +11,7 @@ $(eval $(call gb_UIConfig_UIConfig,sfx)) $(eval $(call gb_UIConfig_add_uifiles,sfx,\ sfx2/uiconfig/ui/alienwarndialog \ + sfx2/uiconfig/ui/addtargetdialog \ sfx2/uiconfig/ui/autoredactdialog \ sfx2/uiconfig/ui/bookmarkdialog \ sfx2/uiconfig/ui/bookmarkmenu \ diff --git a/include/sfx2/autoredactdialog.hxx b/sfx2/inc/autoredactdialog.hxx index 8de264871154..26b29bf10cf5 100644 --- a/include/sfx2/autoredactdialog.hxx +++ b/sfx2/inc/autoredactdialog.hxx @@ -7,8 +7,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef INCLUDED_SFX2_AUTOREDACTDIALOG_HXX -#define INCLUDED_SFX2_AUTOREDACTDIALOG_HXX +#ifndef INCLUDED_SFX2_INC_AUTOREDACTDIALOG_HXX +#define INCLUDED_SFX2_INC_AUTOREDACTDIALOG_HXX #include <memory> #include <sal/config.h> @@ -25,6 +25,10 @@ class Button; } namespace weld { +class ComboBox; +} +namespace weld +{ class Label; } namespace weld @@ -36,16 +40,26 @@ namespace weld class TreeView; } +enum RedactionTargetType +{ + REDACTION_TARGET_TEXT, + REDACTION_TARGET_REGEX, + REDACTION_TARGET_PREDEFINED, + REDACTION_TARGET_UNKNOWN +}; + +/// Keeps information for a single redaction target struct RedactionTarget { - sal_uInt32 nID; OUString sName; - OUString sType; + RedactionTargetType sType; + OUString sContent; bool bCaseSensitive; bool bWholeWords; - OUString sDescription; + sal_uInt32 nID; }; +/// Used to display the targets list class TargetsTable { std::unique_ptr<weld::TreeView> m_xControl; @@ -75,7 +89,7 @@ public: class SFX2_DLLPUBLIC SfxAutoRedactDialog : public SfxDialogController { SfxObjectShellLock m_xDocShell; - std::vector<std::pair<TargetsTable*, OUString>> m_aTableTargets; + std::vector<std::pair<RedactionTarget*, OUString>> m_aTableTargets; std::unique_ptr<weld::Label> m_xRedactionTargetsLabel; std::unique_ptr<TargetsTable> m_xTargetsBox; @@ -85,6 +99,12 @@ class SFX2_DLLPUBLIC SfxAutoRedactDialog : public SfxDialogController std::unique_ptr<weld::Button> m_xEditBtn; std::unique_ptr<weld::Button> m_xDeleteBtn; + /*DECL_LINK(LoadHdl, weld::Button&, void); + DECL_LINK(SaveHdl, weld::Button&, void);*/ + DECL_LINK(AddHdl, weld::Button&, void); + //DECL_LINK(EditHdl, weld::Button&, void); + DECL_LINK(DeleteHdl, weld::Button&, void); + public: SfxAutoRedactDialog(weld::Window* pParent); virtual ~SfxAutoRedactDialog() override; @@ -99,6 +119,28 @@ public: // TODO: Some method(s) to load/save redaction target sets }; +class SfxAddTargetDialog : public weld::GenericDialogController +{ +private: + std::unique_ptr<weld::Entry> m_xName; + std::unique_ptr<weld::ComboBox> m_xType; + std::unique_ptr<weld::Entry> m_xContent; + std::unique_ptr<weld::CheckButton> m_xCaseSensitive; + std::unique_ptr<weld::CheckButton> m_xWholeWords; + +public: + SfxAddTargetDialog(weld::Window* pWindow, const OUString& rName); + + OUString getName() const { return m_xName->get_text(); } + RedactionTargetType getType() const; + OUString getContent() const { return m_xContent->get_text(); } + bool isCaseSensitive() const + { + return m_xCaseSensitive->get_state() == TriState::TRISTATE_TRUE; + } + bool isWholeWords() const { return m_xWholeWords->get_state() == TriState::TRISTATE_TRUE; } +}; + #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sfx2/source/doc/autoredactdialog.cxx b/sfx2/source/doc/autoredactdialog.cxx index 0974a4f03b27..5d94906e9ba8 100644 --- a/sfx2/source/doc/autoredactdialog.cxx +++ b/sfx2/source/doc/autoredactdialog.cxx @@ -8,7 +8,7 @@ */ #include <osl/file.hxx> -#include <sfx2/autoredactdialog.hxx> +#include <autoredactdialog.hxx> #include <vcl/layout.hxx> #include <vcl/idle.hxx> #include <vcl/gdimtf.hxx> @@ -50,17 +50,43 @@ int TargetsTable::GetRowByTargetName(const OUString& sName) TargetsTable::TargetsTable(std::unique_ptr<weld::TreeView> xControl) : m_xControl(std::move(xControl)) { - m_xControl->set_size_request(550, 250); + m_xControl->set_size_request(555, 250); std::vector<int> aWidths; aWidths.push_back(100); - aWidths.push_back(45); - aWidths.push_back(110); + aWidths.push_back(50); + aWidths.push_back(200); + aWidths.push_back(105); aWidths.push_back(105); - aWidths.push_back(150); m_xControl->set_column_fixed_widths(aWidths); m_xControl->set_selection_mode(SelectionMode::Multiple); } +namespace +{ +OUString getTypeName(RedactionTargetType nType) +{ + OUString sTypeName("Unknown"); + + switch (nType) + { + case RedactionTargetType::REDACTION_TARGET_TEXT: + sTypeName = "Text"; + break; + case RedactionTargetType::REDACTION_TARGET_REGEX: + sTypeName = "Regex"; + break; + case RedactionTargetType::REDACTION_TARGET_PREDEFINED: + sTypeName = "Predefined"; + break; + case RedactionTargetType::REDACTION_TARGET_UNKNOWN: + sTypeName = "Unknown"; + break; + } + + return sTypeName; +} +} + void TargetsTable::InsertTarget(RedactionTarget* pTarget) { if (!pTarget) @@ -78,10 +104,10 @@ void TargetsTable::InsertTarget(RedactionTarget* pTarget) // Add to the end int nRow = m_xControl->n_children(); m_xControl->append(OUString::number(reinterpret_cast<sal_Int64>(pTarget)), pTarget->sName); - m_xControl->set_text(nRow, pTarget->sType, 1); - m_xControl->set_text(nRow, pTarget->bCaseSensitive ? OUString("Yes") : OUString("No"), 2); - m_xControl->set_text(nRow, pTarget->bWholeWords ? OUString("Yes") : OUString("No"), 3); - m_xControl->set_text(nRow, pTarget->sDescription, 4); + m_xControl->set_text(nRow, getTypeName(pTarget->sType), 1); + m_xControl->set_text(nRow, pTarget->sContent, 2); + m_xControl->set_text(nRow, pTarget->bCaseSensitive ? OUString("Yes") : OUString("No"), 3); + m_xControl->set_text(nRow, pTarget->bWholeWords ? OUString("Yes") : OUString("No"), 4); } void TargetsTable::SelectByName(const OUString& sName) @@ -121,6 +147,107 @@ OUString TargetsTable::GetNameProposal() return sDefaultTargetName + " " + OUString::number(nHighestTargetId + 1); } +/*IMPL_LINK_NOARG(SfxAutoRedactDialog, LoadHdl, weld::Button&, void) +{ + //TODO: Implement + //Load a targets list from a previously saved file (a json file in the user profile dir?) +} + +IMPL_LINK_NOARG(SfxAutoRedactDialog, SaveHdl, weld::Button&, void) +{ + //TODO: Implement + //Allow saving the targets into a file +}*/ + +IMPL_LINK_NOARG(SfxAutoRedactDialog, AddHdl, weld::Button&, void) +{ + // Open the Add Target dialog, craete a new target and insert into the targets vector and the listbox + SfxAddTargetDialog aAddTargetDialog(getDialog(), m_xTargetsBox->GetNameProposal()); + + bool bIncomplete; + do + { + bIncomplete = false; + + if (aAddTargetDialog.run() != RET_OK) + return; + + if (aAddTargetDialog.getName().isEmpty() + || aAddTargetDialog.getType() == RedactionTargetType::REDACTION_TARGET_UNKNOWN + || aAddTargetDialog.getContent().isEmpty()) + { + bIncomplete = true; + std::unique_ptr<weld::MessageDialog> xBox( + Application::CreateMessageDialog(getDialog(), VclMessageType::Warning, + VclButtonsType::Ok, "All fields are required")); + xBox->run(); + } + else if (m_xTargetsBox->GetTargetByName(aAddTargetDialog.getName())) + { + bIncomplete = true; + std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog( + getDialog(), VclMessageType::Warning, VclButtonsType::Ok, + "There is already a target with this name")); + xBox->run(); + } + + } while (bIncomplete); + + //Alright, we now have everything we need to construct a new target + RedactionTarget* redactiontarget = new RedactionTarget( + { aAddTargetDialog.getName(), aAddTargetDialog.getType(), aAddTargetDialog.getContent(), + aAddTargetDialog.isCaseSensitive(), aAddTargetDialog.isWholeWords(), 0 }); + + // Only the visual/display part + m_xTargetsBox->InsertTarget(redactiontarget); + + // Actually add to the targets vector + if (m_xTargetsBox->GetTargetByName(redactiontarget->sName)) + m_aTableTargets.emplace_back(redactiontarget, redactiontarget->sName); + else + { + std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog( + getDialog(), VclMessageType::Warning, VclButtonsType::Ok, + "An error occured while adding new target. Please report this incidence.")); + xBox->run(); + delete redactiontarget; + } +} + +/*IMPL_LINK_NOARG(SfxAutoRedactDialog, EditHdl, weld::Button&, void) +{ + //TODO: Implement + //Reuse the Add Target dialog +}*/ + +IMPL_LINK_NOARG(SfxAutoRedactDialog, DeleteHdl, weld::Button&, void) +{ + std::vector<int> aSelectedRows = m_xTargetsBox->get_selected_rows(); + + //No selection, so nothing to delete + if (aSelectedRows.empty()) + return; + + if (aSelectedRows.size() > 1) + { + OUString sMsg("Are you sure you would like to delete " + + OUString::number(aSelectedRows.size()) + " targets at once?"); + //Warn the user about multiple deletions + std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog( + getDialog(), VclMessageType::Question, VclButtonsType::OkCancel, sMsg)); + if (xBox->run() == RET_CANCEL) + return; + } + + // After each delete, the indexes of the following items decrease by one. + int delta = 0; + for (const auto& i : aSelectedRows) + { + m_aTableTargets.erase(m_aTableTargets.begin() + (i - delta)); + m_xTargetsBox->remove(i - delta++); + } +} + SfxAutoRedactDialog::SfxAutoRedactDialog(weld::Window* pParent) : SfxDialogController(pParent, "sfx/ui/autoredactdialog.ui", "AutoRedactDialog") , m_xRedactionTargetsLabel(m_xBuilder->weld_label("labelRedactionTargets")) @@ -147,19 +274,14 @@ SfxAutoRedactDialog::SfxAutoRedactDialog(weld::Window* pParent) //m_aTargets.Update(); } - // fill the targets box - /*const sal_uInt16 nCount = m_aTemplates.GetRegionCount(); - if (nCount) - { - for(sal_uInt16 i = 0; i < nCount; ++i) - m_xRegionLb->append_text(m_aTemplates.GetFullRegionName(i)); - m_xRegionLb->connect_changed(LINK(this, SfxNewFileDialog, RegionSelect)); - }*/ - - /*RedactionTarget* redactiontarget - = new RedactionTarget({ 0, "Target 1", "String", true, false, "Some description" }); + // TODO: fill the targets box - m_xTargetsBox->InsertTarget(redactiontarget);*/ + // Handler connections + //m_xLoadBtn->connect_clicked(LINK(this, SfxAutoRedactDialog, LoadHdl)); + //m_xSaveBtn->connect_clicked(LINK(this, SfxAutoRedactDialog, SaveHdl)); + m_xAddBtn->connect_clicked(LINK(this, SfxAutoRedactDialog, AddHdl)); + //m_xEditBtn->connect_clicked(LINK(this, SfxAutoRedactDialog, EditHdl)); + m_xDeleteBtn->connect_clicked(LINK(this, SfxAutoRedactDialog, DeleteHdl)); } SfxAutoRedactDialog::~SfxAutoRedactDialog() @@ -178,4 +300,30 @@ bool SfxAutoRedactDialog::hasTargets() const return true; } +SfxAddTargetDialog::SfxAddTargetDialog(weld::Window* pParent, const OUString& rName) + : GenericDialogController(pParent, "sfx/ui/addtargetdialog.ui", "AddTargetDialog") + , m_xName(m_xBuilder->weld_entry("name")) + , m_xType(m_xBuilder->weld_combo_box("type")) + , m_xContent(m_xBuilder->weld_entry("content")) + , m_xCaseSensitive(m_xBuilder->weld_check_button("checkboxCaseSensitive")) + , m_xWholeWords(m_xBuilder->weld_check_button("checkboxWholeWords")) +{ + m_xName->set_text(rName); + m_xName->select_region(0, rName.getLength()); +} + +RedactionTargetType SfxAddTargetDialog::getType() const +{ + OUString sTypeID = m_xType->get_active_id(); + + if (sTypeID == "text") + return RedactionTargetType::REDACTION_TARGET_TEXT; + else if (sTypeID == "regex") + return RedactionTargetType::REDACTION_TARGET_REGEX; + else if (sTypeID == "predefined") + return RedactionTargetType::REDACTION_TARGET_PREDEFINED; + else + return RedactionTargetType::REDACTION_TARGET_UNKNOWN; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sfx2/source/doc/objserv.cxx b/sfx2/source/doc/objserv.cxx index feb8952f4c23..f4c941cba5f5 100644 --- a/sfx2/source/doc/objserv.cxx +++ b/sfx2/source/doc/objserv.cxx @@ -125,7 +125,7 @@ #include <svx/unoshape.hxx> #include <com/sun/star/util/Color.hpp> -#include <sfx2/autoredactdialog.hxx> +#include <autoredactdialog.hxx> using namespace ::com::sun::star; using namespace ::com::sun::star::lang; diff --git a/sfx2/uiconfig/ui/addtargetdialog.ui b/sfx2/uiconfig/ui/addtargetdialog.ui new file mode 100644 index 000000000000..3d45c7a240bd --- /dev/null +++ b/sfx2/uiconfig/ui/addtargetdialog.ui @@ -0,0 +1,235 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.22.1 --> +<interface domain="sw"> + <requires lib="gtk+" version="3.18"/> + <object class="GtkDialog" id="AddTargetDialog"> + <property name="can_focus">False</property> + <property name="border_width">6</property> + <property name="title" translatable="yes" context="addtargetdialog|AddTargetDialog">Add Target</property> + <property name="modal">True</property> + <property name="default_width">0</property> + <property name="default_height">0</property> + <property name="type_hint">dialog</property> + <child> + <placeholder/> + </child> + <child internal-child="vbox"> + <object class="GtkBox" id="dialog-vbox1"> + <property name="can_focus">False</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <property name="orientation">vertical</property> + <property name="spacing">12</property> + <child internal-child="action_area"> + <object class="GtkButtonBox"> + <property name="can_focus">False</property> + <child> + <object class="GtkButton" id="cancel"> + <property name="label">gtk-cancel</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack_type">end</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="close"> + <property name="label">gtk-ok</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack_type">end</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="help"> + <property name="label">gtk-help</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + <property name="secondary">True</property> + </packing> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">5</property> + </packing> + </child> + <child> + <object class="GtkGrid"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkLabel" id="label_name"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes" context="addtargetdialog|label_name">Name:</property> + <property name="use_underline">True</property> + <accessibility> + <relation type="label-for" target="name"/> + </accessibility> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="name"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="margin_left">2</property> + <property name="margin_bottom">2</property> + <property name="activates_default">True</property> + <accessibility> + <relation type="labelled-by" target="label_name"/> + </accessibility> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label_type"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes" context="addtargetdialog|label_type">Type:</property> + <property name="use_underline">True</property> + <accessibility> + <relation type="label-for" target="type"/> + </accessibility> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label_content"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes" context="addtargetdialog|label_content">Content:</property> + <property name="use_underline">True</property> + <accessibility> + <relation type="label-for" target="content"/> + </accessibility> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">2</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="content"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="margin_left">2</property> + <property name="activates_default">True</property> + <accessibility> + <relation type="labelled-by" target="label_content"/> + </accessibility> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">2</property> + </packing> + </child> + <child> + <object class="GtkComboBoxText" id="type"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <items> + <item id="text" translatable="yes" context="addtargetdialog|type">Text</item> + <item id="regex" translatable="yes" context="addtargetdialog|type">Regex</item> + <item id="predefined" translatable="yes" context="addtargetdialog|type">Predefined</item> + </items> + <accessibility> + <relation type="labelled-by" target="label_type"/> + </accessibility> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkCheckButton" id="checkboxCaseSensitive"> + <property name="label" translatable="yes" context="addtargetdialog|checkboxCaseSensitive">Case Sensitive</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="halign">start</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="checkboxWholeWords"> + <property name="label" translatable="yes" context="addtargetdialog|checkboxWholeWords">Whole Words Only</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="halign">start</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack_type">end</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + </object> + </child> + <action-widgets> + <action-widget response="-6">cancel</action-widget> + <action-widget response="-5">close</action-widget> + <action-widget response="-11">help</action-widget> + </action-widgets> + </object> +</interface> diff --git a/sfx2/uiconfig/ui/autoredactdialog.ui b/sfx2/uiconfig/ui/autoredactdialog.ui index 01c0dc6e9592..113002775125 100644 --- a/sfx2/uiconfig/ui/autoredactdialog.ui +++ b/sfx2/uiconfig/ui/autoredactdialog.ui @@ -8,12 +8,12 @@ <column type="gchararray"/> <!-- column-name sType --> <column type="gchararray"/> + <!-- column-name sContent --> + <column type="gchararray"/> <!-- column-name bIsCaseSensitive --> <column type="gchararray"/> <!-- column-name bWholeWords --> <column type="gchararray"/> - <!-- column-name sDescription --> - <column type="gchararray"/> <!-- column-name id --> <column type="gchararray"/> </columns> @@ -143,7 +143,7 @@ <object class="GtkTreeViewColumn" id="treeviewcolumn2"> <property name="resizable">True</property> <property name="spacing">6</property> - <property name="title" translatable="yes" context="autoredactdialog|target">Case Sensitive</property> + <property name="title" translatable="yes" context="autoredactdialog|target">Content</property> <child> <object class="GtkCellRendererText" id="cellrenderer2"/> <attributes> @@ -156,7 +156,7 @@ <object class="GtkTreeViewColumn" id="treeviewcolumn3"> <property name="resizable">True</property> <property name="spacing">6</property> - <property name="title" translatable="yes" context="autoredactdialog|target">Whole Words</property> + <property name="title" translatable="yes" context="autoredactdialog|target">Case Sensitive</property> <child> <object class="GtkCellRendererText" id="cellrenderer3"/> <attributes> @@ -169,7 +169,7 @@ <object class="GtkTreeViewColumn" id="treeviewcolumn4"> <property name="resizable">True</property> <property name="spacing">6</property> - <property name="title" translatable="yes" context="autoredactdialog|target">Description</property> + <property name="title" translatable="yes" context="autoredactdialog|target">Whole Words</property> <child> <object class="GtkCellRendererText" id="cellrenderer4"/> <attributes> |