From 53a4f3cef248107cd0abfe89b9f7bc2199b7d11d Mon Sep 17 00:00:00 2001 From: Vincent Reher Date: Tue, 3 Oct 2023 08:52:15 -0700 Subject: [PATCH] Changes to bring code up to date and to synchronize with current changes in https://mirror.git.trinitydesktop.org/gitea/TDE/tdelibs/pulls/209. Code now includes GUI enabling user to change TDEHiddenFileMatcher for current KDirLister. Signed-off-by: Vincent Reher --- konqueror/listview/konq_listview.cpp | 53 ++- konqueror/listview/konq_listviewitems.cpp | 2 +- libkonq/CMakeLists.txt | 3 + libkonq/update_tdestringmatcher.cpp | 55 +++ libkonq/update_tdestringmatcher.h | 21 + libkonq/update_tdestringmatcher_dialog.cpp | 520 +++++++++++++++++++++ libkonq/update_tdestringmatcher_dialog.h | 118 +++++ 7 files changed, 755 insertions(+), 17 deletions(-) create mode 100644 libkonq/update_tdestringmatcher.cpp create mode 100644 libkonq/update_tdestringmatcher.h create mode 100755 libkonq/update_tdestringmatcher_dialog.cpp create mode 100644 libkonq/update_tdestringmatcher_dialog.h diff --git a/konqueror/listview/konq_listview.cpp b/konqueror/listview/konq_listview.cpp index a611c388d..184475b9d 100644 --- a/konqueror/listview/konq_listview.cpp +++ b/konqueror/listview/konq_listview.cpp @@ -49,6 +49,8 @@ #include #include +#include +#include KonqListViewFactory::KonqListViewFactory() { @@ -273,10 +275,19 @@ KonqListView::KonqListView( TQWidget *parentWidget, TQObject *parent, const char m_sortColumnIndexPrimary = 0; m_sortColumnIndexAlternate = 1; + TSMTRACE << "KonqListView::KonqListView: Begin initializing KDirLister->hiddenFileSpec" << endl; TQString hiddenFileSpec = m_pProps->hiddenFileSpec() ; - if ( ! hiddenFileSpec.isNull() ) { - m_pListView->m_dirLister->matcher->setCriteria( hiddenFileSpec ); - } // otherwise we rely on matcher's default criteria + if ( hiddenFileSpec.isEmpty() ) { + // Use global (default) matcher criteria + TSMTRACE << "KonqListView::KonqListView: using Global HFM pattern string" << endl; + TDEStringMatcher *globalMatcher = TDEGlobal::hiddenFileMatcher(); + hiddenFileSpec = globalMatcher->getMatchSpecString(); + TSMTRACE << "KonqListView::KonqListView: just finished with global getMatchSpecString(): " << hiddenFileSpec << endl; + } else { + TSMTRACE << "KonqListView::KonqListView: using view-specific pattern string" << endl; + } + m_pListView->m_dirLister->hiddenFileMatcher()->setMatchSpecs( hiddenFileSpec ); + TSMTRACE << "KonqListView::KonqListView: Done initializing KDirLister->hiddenFileMatcher" << endl; setupActions(); @@ -496,31 +507,42 @@ void KonqListView::slotChangeHiddenFileMatcher() slotShowDot(); } - int result = m_pListView->m_dirLister->matcher->getMatchPropertiesFromUser( "Konqueror Listview" ) ; + // int result = m_pListView->m_dirLister->hiddenFileMatcher->getMatchPropertiesFromUser( "Define 'Hidden' for
Konqueror Listview" ); + TSMTRACE << "KonqListView::slotChangeHiddenFileMatcher using next generation dialog" << endl; + UIresult result = getTDEStringMatcherPatternsFromUser( + m_pListView->m_dirLister->hiddenFileMatcher(), "Define 'Hidden' for Konqueror Listview" + ); switch ( result ) { - case TDEIO::HiddenFileMatcher::criteriaUnchanged: + + case UIresult::NOCHANGE : if ( ! wasShowingHidden ) { m_paShowDot->setChecked( FALSE ); slotShowDot(); } return; break; - case TDEIO::HiddenFileMatcher::criteriaApplied: - // On-the-fly change + + case UIresult::APPLY : + // On-the-fly change to hiddenFileMatcher made by getMatchPropertiesFromUser() break; - case TDEIO::HiddenFileMatcher::saveCriteria: - m_pProps->setHiddenFileSpec( m_pListView->m_dirLister->matcher->getCriteria() ); + + case UIresult::SAVE : + // On-the-fly change to hiddenFileMatcher made by getMatchPropertiesFromUser(), store it + m_pProps->setHiddenFileSpec( m_pListView->m_dirLister->hiddenFileMatcher()->getMatchSpecString() ); break; - case TDEIO::HiddenFileMatcher::reloadCriteria: + + case UIresult::RELOAD : TQString hiddenFileSpec = m_pProps->hiddenFileSpec() ; - if ( ! hiddenFileSpec.isNull() ) { + if ( ! hiddenFileSpec.isEmpty() ) { // Reload from current listview setting - m_pListView->m_dirLister->matcher->setCriteria( hiddenFileSpec ); + TSMTRACE << "KonqListView::slotChangeHiddenFileMatcher: reloading view-specific match criteria" << endl; + m_pListView->m_dirLister->hiddenFileMatcher()->setMatchSpecs( hiddenFileSpec ); } else { // Reload from current systemwide default setting - TDEIO::HiddenFileMatcher *commonMatcher = TDEIO::CommonHiddenFileMatcher::getMatcher(); - m_pListView->m_dirLister->matcher->setCriteria( commonMatcher->getCriteria() ); + TSMTRACE << "KonqListView::slotChangeHiddenFileMatcher: reloading global match criteria" << endl; + TDEStringMatcher *globalMatcher = TDEGlobal::hiddenFileMatcher(); + m_pListView->m_dirLister->hiddenFileMatcher()->setMatchSpecs( globalMatcher->getMatchSpecString() ); } break; } @@ -533,8 +555,7 @@ void KonqListView::slotChangeHiddenFileMatcher() // "Show Hidden Files" option m_paShowDot->setChecked( wasShowingHidden ); - slotShowDot(); // - + slotShowDot(); } void KonqListView::slotShowDot() diff --git a/konqueror/listview/konq_listviewitems.cpp b/konqueror/listview/konq_listviewitems.cpp index 5b9ef230f..8d4b8e583 100644 --- a/konqueror/listview/konq_listviewitems.cpp +++ b/konqueror/listview/konq_listviewitems.cpp @@ -96,7 +96,7 @@ void KonqListViewItem::updateContents() sortChar = S_ISDIR( m_fileitem->mode() ) ? 1 : 3; else sortChar = 3; - if ( m_fileitem->isHidden( m_pListViewWidget->m_dirLister->matcher ) ) + if ( m_groupHiddenFirst && m_fileitem->isHidden() ) --sortChar; //now we have the first column, so let's do the rest diff --git a/libkonq/CMakeLists.txt b/libkonq/CMakeLists.txt index c1780780d..59801ceff 100644 --- a/libkonq/CMakeLists.txt +++ b/libkonq/CMakeLists.txt @@ -44,6 +44,8 @@ install( FILES kivdirectoryoverlay.h kivfreespaceoverlay.h konq_faviconmgr.h konq_xmlguiclient.h konqbookmarkmanager.h konq_filetip.h konq_sort_constants.h konq_string_compare.h + update_tdestringmatcher.h + DESTINATION ${INCLUDE_INSTALL_DIR} ) @@ -72,6 +74,7 @@ tde_add_library( konq SHARED AUTOMOC konq_undo.skel konq_historymgr.cpp konq_historycomm.cpp konq_historycomm.skel konq_pixmapprovider.cpp kivdirectoryoverlay.cpp kivfreespaceoverlay.cpp konq_faviconmgr.cpp konq_faviconmgr.skel konq_filetip.cpp + update_tdestringmatcher_dialog.cpp update_tdestringmatcher.cpp VERSION 4.2.0 LINK tdeparts-shared DESTINATION ${LIB_INSTALL_DIR} diff --git a/libkonq/update_tdestringmatcher.cpp b/libkonq/update_tdestringmatcher.cpp new file mode 100644 index 000000000..f46447d95 --- /dev/null +++ b/libkonq/update_tdestringmatcher.cpp @@ -0,0 +1,55 @@ +#include "update_tdestringmatcher.h" +#include "update_tdestringmatcher_dialog.h" + +#include + +UIresult +getTDEStringMatcherPatternsFromUser( + TDEStringMatcher *matcher, + TQString dialogTitle +) +{ + TDEStringMatcher::MatchSpecList matchSpecs = matcher->getMatchSpecs(); + TDEStringMatcher_UI *tsmDialog = new TDEStringMatcher_UI( matchSpecs, dialogTitle ); + tsmDialog->exec(); + UIresult requested_action; + if ( tsmDialog->result() ) { + requested_action = tsmDialog->getDialogResult(); + } + else { + requested_action = UIresult::NOCHANGE; + } + + switch ( requested_action ) { + case UIresult::NOCHANGE : + TSMTRACE + << "TDEStringMatcherUI::getMatchPropertiesFromUser: user edit cancelled" << endl; + return requested_action; + break; + case UIresult::RELOAD : + TSMTRACE + << "TDEStringMatcherUI::getMatchPropertiesFromUser: user asking caller to reload stored pattern" << endl; + return requested_action; + break; + } + + if ( matcher->setMatchSpecs( tsmDialog->getMatchSpecs() ) ) { + TSMTRACE + << "TDEStringMatcherUI::getMatchPropertiesFromUser: user edits applied: '" + << matcher->getMatchSpecString() << "'" << endl; + } + + else { + TSMTRACE + << "TDEStringMatcherUI::getMatchPropertiesFromUser: user edits rejected" << endl; + return UIresult::NOCHANGE; + } + + + if ( requested_action == UIresult::RELOAD ) { + TSMTRACE + << "TDEStringMatcherUI::getMatchPropertiesFromUser: user asking caller to save updated criteria string" << endl; + } + + return requested_action; +} diff --git a/libkonq/update_tdestringmatcher.h b/libkonq/update_tdestringmatcher.h new file mode 100644 index 000000000..cd0269f07 --- /dev/null +++ b/libkonq/update_tdestringmatcher.h @@ -0,0 +1,21 @@ +#ifndef UPDATE_TDESTRINGMATCHER_H +#define UPDATE_TDESTRINGMATCHER_H + +#include +#include + +enum class UIresult: signed char +{ + NOCHANGE = -1, // No change + APPLY = 0, // Change applied + SAVE = 1, // Change applied, request save + RELOAD = 2 // No change, request reload +}; + +UIresult +getTDEStringMatcherPatternsFromUser( + TDEStringMatcher *matcher, + TQString dialogTitle +); + +#endif diff --git a/libkonq/update_tdestringmatcher_dialog.cpp b/libkonq/update_tdestringmatcher_dialog.cpp new file mode 100755 index 000000000..bd7813666 --- /dev/null +++ b/libkonq/update_tdestringmatcher_dialog.cpp @@ -0,0 +1,520 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "update_tdestringmatcher.h" +#include "update_tdestringmatcher_dialog.h" + +#include + +TDEStringMatcher_UI::TDEStringMatcher_UI( + TDEStringMatcher::MatchSpecList& data, + TQString title +) +{ + int fontHeight = this->fontMetrics().height(); + int fontLeading = this->fontMetrics().leading(); + int defaultLineSpacing = this->fontMetrics().lineSpacing(); + //int defaultLineSpacing = this->fontMetrics().height() ; + int defaultMargin = this->fontMetrics().maxWidth() / 4; + //int defaultMargin = this->fontMetrics().width("W"); + + setName( "TDEStringMatcher_UI" ); + main_vbl = new TQVBoxLayout( this, 11, 6, "main_vbl"); + + //------------------------------------------------------------------------- + // Section 1 (horizontal): 2-parts + //------------------------------------------------------------------------- + + sec1X_hbl = new TQHBoxLayout( 0, 0, 0, "sec1X_hbl" ); + sec1X_hbl->setAlignment( TQt::AlignTop ); + sec1X_hbl->setSpacing( defaultLineSpacing ); + sec1X_hbl->setMargin( defaultMargin ); + + //------------------------------------------------------------------------- + // Section 1A (vertical): 2 parts: label, listbox + //------------------------------------------------------------------------- + + sec1A_vbl = new TQVBoxLayout( 0, 0, 0, "sec1A_vbl"); + sec1A_vbl->setAlignment( TQt::AlignTop ); + sec1X_hbl->addLayout( sec1A_vbl ); + + lbl_patternListHeader = new TQLabel( this, "&Pattern List" ); + lbl_patternListHeader->setText( i18n( "Match Patterns" ) ); + lbl_patternListHeader->setAlignment( TQt::AlignHCenter ); + sec1A_vbl->addWidget( lbl_patternListHeader ) ; + + lb_patternList = new TQListBox( this, "lb_patternList" ); + sec1A_vbl->addWidget( lb_patternList ); + + //------------------------------------------------------------------------- + // Section 1B (vertical): 4 parts + //------------------------------------------------------------------------- + + sec1B_vbl = new TQVBoxLayout( 0, 0, 0, "sec1B_vbl"); + sec1B_vbl->setAlignment( TQt::AlignCenter ); + sec1B_vbl->setSpacing( defaultLineSpacing ); + sec1B_vbl->setMargin( defaultMargin ); + sec1X_hbl->addLayout( sec1B_vbl ); + + //------------------------------------------------------------------------- + // Section 1B, part 1: lineedit + 2 buttons + //------------------------------------------------------------------------- + + sec1B1_vbx = new TQGroupBox( this, "sec1B1_vbx"); + sec1B1_vbx->setTitle( i18n( "Modify Patterns" ) ); + sec1B1_vbx->setAlignment( TQGroupBox::AlignHCenter ); + sec1B1_vbx ->setColumnLayout(0, TQt::Vertical ); + + sec1B1_vbl = new TQVBoxLayout( sec1B1_vbx->layout() ); + sec1B1_vbl->setMargin( defaultMargin ); + sec1B_vbl->addWidget( sec1B1_vbx ); + + le_editPattern = new TQLineEdit( sec1B1_vbx, "le_editPattern" ); + TQToolTip::add( le_editPattern, i18n( "Modify highlighted pattern" ) ); + sec1B1_vbl->addWidget( le_editPattern ); + + pb_addPattern = new TQPushButton( sec1B1_vbx, "pb_addPattern" ); + pb_addPattern->setText( i18n( "&New pattern" ) ); + TQToolTip::add( pb_addPattern, i18n( "Add new pattern to list" ) ); + pb_addPattern->setAutoDefault( false ); + pb_addPattern->setDefault( false ); + sec1B1_vbl->addWidget( pb_addPattern ); + + pb_delPattern = new TQPushButton( sec1B1_vbx, "pb_delPattern" ); + pb_delPattern->setText( i18n( "&Delete pattern" ) ); + TQToolTip::add( pb_delPattern, i18n( "Delete highlighted pattern from list" ) ); + pb_addPattern->setAutoDefault( false ); + pb_addPattern->setDefault( false ); + sec1B1_vbl->addWidget( pb_delPattern ); + + //------------------------------------------------------------------------- + // Section 1B, part 2: 3 comboboxes + //------------------------------------------------------------------------- + + sec1B2_vbx = new TQGroupBox( this, "sec1B2_vbx"); + sec1B2_vbx->setTitle( i18n( "Pattern Match &Options" ) ); + sec1B2_vbx->setAlignment( TQGroupBox::AlignHCenter ); + sec1B2_vbx ->setColumnLayout(0, TQt::Vertical ); + + sec1B2_vbl = new TQVBoxLayout( sec1B2_vbx->layout() ); + sec1B2_vbl->setMargin( defaultMargin ); + sec1B_vbl->addWidget( sec1B2_vbx ); + + cb_patternType = new TQComboBox( FALSE, sec1B2_vbx, "cb_patternType" ); + TQToolTip::add( cb_patternType, i18n( "Highlighted pattern type" ) ); + cb_patternType->insertItem( i18n( "Pattern is a Regex" ) ); // PatternType::REGEX + cb_patternType->insertItem( i18n( "Pattern is a POSIX Wildcard expression" ) ); // PatternType::WILDCARD + cb_patternType->insertItem( i18n( "Pattern is a simple substring" ) ); // PatternType::SUBSTRING + cb_patternType->setCurrentItem( 0 ); + sec1B2_vbl->addWidget( cb_patternType ) ; + + cb_ancHandling = new TQComboBox( FALSE, sec1B2_vbx, "cb_ancHandling" ); + TQToolTip::add( cb_ancHandling, i18n( "Alphabetic case handling" ) ); + cb_ancHandling->insertItem( i18n( "Alphabetic letter variants distinct" ) ); // ANCHandling::CASE_SENSITIVE + cb_ancHandling->insertItem( i18n( "Upper and lower case letters are same" ) ); // ANCHandling::CASE_INSENSITIVE + cb_ancHandling->insertItem( i18n( "Alphanumeric character variants are same" ) ); // ANCHandling::IGNORE_DIACRITICS + cb_ancHandling->setCurrentItem( 0 ); + sec1B2_vbl->addWidget( cb_ancHandling ) ; + + cb_expectMatch = new TQComboBox( FALSE, sec1B2_vbx, "cb_expectMatch" ); + TQToolTip::add( cb_expectMatch, i18n( "Match pattern or not?" ) ); + cb_expectMatch->insertItem( i18n( "Does NOT match pattern" ) ); + cb_expectMatch->insertItem( i18n( "Matches pattern" ) ); + cb_expectMatch->setCurrentItem( 1 ); + sec1B2_vbl->addWidget( cb_expectMatch ) ; + + //------------------------------------------------------------------------- + // Section 1B, part 3: spacer + //------------------------------------------------------------------------- + + pad1B3 = new TQSpacerItem( 0, 0, TQSizePolicy::Minimum, TQSizePolicy::Expanding ); + sec1B_vbl->addItem( pad1B3 ); + + //------------------------------------------------------------------------- + // Section 1B, part 4: radio button group + //------------------------------------------------------------------------- + + // Create a group of radio buttons + bg_Disposition = new TQButtonGroup( this, "bg_Disposition" ); + bg_Disposition->setTitle( i18n( "Disposition of &Changes" ) ); + bg_Disposition->setAlignment( TQGroupBox::AlignHCenter ); + //bg_Disposition->setFlat( true ); + bg_Disposition->setRadioButtonExclusive(true); + sec1B_vbl->addWidget( bg_Disposition ); + + // Create a layout for the radio buttons + TQVBoxLayout *sec1B4_vbl = new TQVBoxLayout(bg_Disposition, -1 ); + sec1B4_vbl->setMargin( defaultMargin * 2 ); + sec1B4_vbl->insertSpacing( 0, defaultLineSpacing / 2 ); + + // Set up radio button 0 + rb_ApplyNoSave = new TQRadioButton( bg_Disposition ); + rb_ApplyNoSave->setText( i18n( "&Apply but do not save" ) ); + rb_ApplyNoSave->setChecked( TRUE ); + TQToolTip::add( rb_ApplyNoSave, i18n( "Changes will be applied temporarily" ) ); + sec1B4_vbl->addWidget( rb_ApplyNoSave ); + + // Set up radio button 1 + rb_ApplyAndSave = new TQRadioButton( bg_Disposition ); + rb_ApplyAndSave->setText( i18n( "Apply and &save as default" ) ); + TQToolTip::add( rb_ApplyAndSave, i18n( "Changes will be applied and saved to disk" ) ); + sec1B4_vbl->addWidget( rb_ApplyAndSave ); + + // Set up radio button 2 + rb_RestoreDefault = new TQRadioButton( bg_Disposition ); + rb_RestoreDefault->setText( i18n( "Ignore and restore &default" ) ); + TQToolTip::add( rb_RestoreDefault, i18n( "Changes will be discarded and saved default restored" ) ); + sec1B4_vbl->addWidget( rb_RestoreDefault ); + + //------------------------------------------------------------------------- + // Section 2 (horizontal): horizontal filler + pushbuttone + //------------------------------------------------------------------------- + + sec2X_hbl = new TQHBoxLayout( 0, 0, 6, "sec2X_hbl"); + + pad2_hb = new TQSpacerItem( 111, 0, TQSizePolicy::Expanding, TQSizePolicy::Minimum ); + sec2X_hbl->addItem( pad2_hb ); + + pb_OK = new TQPushButton( this, "pb_OK" ); + pb_OK->setDefault( false ); + pb_OK->setText( i18n( "&OK" ) ); + TQToolTip::add( pb_OK, i18n( "Save settings as default" ) ); + //pb_OK->setAccel( TQKeySequence( "Return" ) ); + sec2X_hbl->addWidget( pb_OK ); + + pb_Cancel = new TQPushButton( this, "pb_Cancel" ); + pb_Cancel->setDefault( false ); + pb_Cancel->setText( i18n( "&Cancel" ) ); + // pb_Cancel->setAccel( TQKeySequence( "Esc" ) ); + sec2X_hbl->addWidget( pb_Cancel ); + + //------------------------------------------------------------------------- + // Final widget assembly & preparation for display + //------------------------------------------------------------------------- + + main_vbl->addLayout( sec1X_hbl ); + main_vbl->addLayout( sec2X_hbl ); + + resize( TQSize(0, 0).expandedTo(minimumSizeHint() * 1.1 ) ); + clearWState( WState_Polished ); + + //------------------------------------------------------------------------- + // Connect UI actions with functions + //------------------------------------------------------------------------- + + connect( lb_patternList, SIGNAL( highlighted(int) ), this, SLOT( displayItemText() ) ); + connect( lb_patternList, SIGNAL( selected(int) ), this, SLOT( editItemText() ) ); + + connect( le_editPattern, SIGNAL( lostFocus() ), this, SLOT( updateItemText() ) ); + connect( le_editPattern, SIGNAL( returnPressed() ), this, SLOT( lineEditReturn() ) ); + + connect( pb_addPattern, SIGNAL( clicked() ), this, SLOT( addItem() ) ); + connect( pb_delPattern, SIGNAL( clicked() ), this, SLOT( removeItem() ) ); + + connect( cb_patternType, SIGNAL( activated(int) ), this, SLOT( updatePatternType(int) ) ); + connect( cb_ancHandling, SIGNAL( activated(int) ), this, SLOT( updateANCHandling(int) ) ); + connect( cb_expectMatch, SIGNAL( activated(int) ), this, SLOT( updateWantMatch(int) ) ); + connect( bg_Disposition, SIGNAL(clicked(int)), this, SLOT(setExitDisposition(int)) ); + + connect( pb_OK, SIGNAL( clicked() ), this, SLOT( accept() ) ); + connect( pb_Cancel, SIGNAL( clicked() ), this, SLOT( reject() ) ); + + DialogEventHandler *le_returnKeyFilter = new DialogEventHandler; + le_editPattern->installEventFilter( le_returnKeyFilter ); + + // tab order + setTabOrder( lb_patternList, le_editPattern ); + setTabOrder( le_editPattern, pb_addPattern ); + setTabOrder( pb_addPattern, pb_delPattern ); + setTabOrder( pb_delPattern, cb_patternType ); + setTabOrder( cb_patternType, cb_ancHandling ); + setTabOrder( cb_ancHandling, cb_expectMatch ); + setTabOrder( cb_expectMatch, rb_ApplyNoSave ); + setTabOrder( rb_ApplyNoSave, rb_ApplyAndSave ); + setTabOrder( rb_ApplyAndSave, rb_RestoreDefault ); + setTabOrder( rb_RestoreDefault, lb_patternList ); + + //------------------------------------------------------------------------- + // Initialize dialog data + //------------------------------------------------------------------------- + + matchSpecs = data; + lb_patternList->clear(); + for (int i = 0 ; i < matchSpecs.count(); i++ ) { + lb_patternList->insertItem(matchSpecs[i].pattern.latin1() ); + //-Debug: fprintf(stdout, "Received spec # %d (%s)\n", i, matchSpecs[i].pattern.latin1() ); + } + + if ( lb_patternList->count() > 0 ) { + lb_patternList->setFocus(); + lb_patternList->setSelected( 0, true ); + } + else { + //-Debug: kdWarning() << "Adding item to othewise empty pattern list" << endl; + addItem(); + } + + dialogResult = UIresult::APPLY; + + if ( title.isEmpty() ) title = i18n( "Update string matching specifications" ); + setCaption( title ); +} + +TDEStringMatcher_UI::~TDEStringMatcher_UI() +{ +} + +//=== Signal handlers ===/ + +void TDEStringMatcher_UI::displayItemText() +{ + /* + Display current TQListBox entry in the TQLineEdit widget + */ + int currentIndex = lb_patternList->currentItem(); + if ( currentIndex < 0 ) return; + le_editPattern->setText( lb_patternList->currentText() ); + cb_patternType->setCurrentItem( (uint) matchSpecs[currentIndex].patternType ); + cb_ancHandling->setCurrentItem( (uint) matchSpecs[currentIndex].ancHandling ); + cb_expectMatch->setCurrentItem( (uint) matchSpecs[currentIndex].expectMatch ); + //-Debug: fprintf( stdout, "Current item # %d ('%s')\n", currentIndex, lb_patternList->currentText().latin1() ) ; +} + +void TDEStringMatcher_UI::editItemText() +{ + /* + Focus on TQLineEdit widget for user editing + */ + le_editPattern->setFocus(); + le_editPattern->selectAll(); + //-Debug: fprintf( stdout, "Editing item # %d ('%s')\n", lb_patternList->currentItem(), lb_patternList->currentText().latin1() ) ; +} + +void TDEStringMatcher_UI::lineEditReturn() +{ + /* + Configure to trigger updateItemText(), effectively + returning focus to corresponding item in the TQListBox widget. + FIXME: This never worked since would always exit the dialog. + As a result, we had to implement eventFilter for TQLineEdit. + */ + updateItemText(); + //fprintf( stdout, "Catching returnPressed() signal in line edit\n" ) ; +} + +void TDEStringMatcher_UI::updateItemText() +{ + /* + Propagate any changes made in the TQLineEdit widget back to + corresponding TQListBox widget item and then focus on that. + */ + + if ( le_editPattern->text().isEmpty() ) return ; + + int currentIndex = lb_patternList->currentItem(); + if( le_editPattern->text() != "" ) + { + if ( currentIndex < 0 ) { + // Add 1st entry to empty back-end list + TDEStringMatcher::MatchSpec newPatternSpec = { + TDEStringMatcher::PatternType::DEFAULT, + TDEStringMatcher::ANCHandling::DEFAULT, + true, + TQString( le_editPattern->text() ) + }; + matchSpecs.push_back( newPatternSpec ); + // Add 1st entry to empty front-end list + lb_patternList->insertItem( le_editPattern->text() ); + lb_patternList->setCurrentItem( 0 ); + } + else { + // Update existing back-end list entry + matchSpecs[currentIndex].pattern = le_editPattern->text() ; + // Update existing front-end list entry + lb_patternList->changeItem( le_editPattern->text(), currentIndex ); + lb_patternList->setFocus(); + } + + // fprintf( stdout, "Modified item # %d ('%s')\n", lb_patternList->currentItem(), lb_patternList->currentText().latin1() ) ; + } + else { + // User did not modify list item, so throw it away + removeItem(); + } +} + +void TDEStringMatcher_UI::addItem() +{ + /* + Add provisional new entry to the TQListBox widget and focus + on the TQLineEdit widget for user modifications. If the entry + is not immediately modified, it will will be removed. + */ + + if ( le_editPattern->text() == "" ) { + // We have not completed prior process of adding new item + editItemText(); + return; + } + + // Complete any pending changes to current item text; + updateItemText(); + + le_editPattern->setText( "" ); + + // Add proposed new entry to back-end list + TDEStringMatcher::MatchSpec newPatternSpec = { + TDEStringMatcher::PatternType::DEFAULT, + TDEStringMatcher::ANCHandling::DEFAULT, + true, + le_editPattern->text() + }; + matchSpecs.push_back( newPatternSpec ); + + // Add proposed new entry to front-end list + lb_patternList->insertItem( le_editPattern->text() ); + int newIndex = lb_patternList->count() - 1; + lb_patternList->setCurrentItem( newIndex ); + + editItemText(); + displayItemText(); + // fprintf( stdout, "Adding provisional item # %d ('%s')\n", lb_patternList->currentItem(), lb_patternList->currentText().latin1() ) ; +} + +void TDEStringMatcher_UI::removeItem() +{ + if( lb_patternList->count() <= 0 ) return ; + + int currentIndex = lb_patternList->currentItem(); + //fprintf( stdout, "Removing item # %d ('%s')\n", currentIndex, lb_patternList->currentText().latin1() ) ; + + // Front-end + lb_patternList->removeItem( lb_patternList->currentItem() ); + le_editPattern->setText(""); + + // Back-end + matchSpecs.erase( matchSpecs.begin() + currentIndex ); + displayItemText(); + lb_patternList->setFocus(); +} + +void TDEStringMatcher_UI::updatePatternType( int selectedNum ) +{ + int currentIndex = lb_patternList->currentItem(); + matchSpecs[currentIndex].patternType = (TDEStringMatcher::PatternType) selectedNum ; + //fprintf( stdout, "updatePatternType(): value changed to %d\n", selectedNum ) ; +} + +void TDEStringMatcher_UI::updateANCHandling( int selectedNum ) +{ + int currentIndex = lb_patternList->currentItem(); + matchSpecs[currentIndex].ancHandling = (TDEStringMatcher::ANCHandling) selectedNum ; + //fprintf( stdout, "updateANCHandling(): value changed to %d\n", selectedNum ) ; +} + +void TDEStringMatcher_UI::updateWantMatch( int index ) +{ + int currentIndex = lb_patternList->currentItem(); + matchSpecs[currentIndex].expectMatch = (bool) index ; +} + +void TDEStringMatcher_UI::setExitDisposition(int buttonNum ) +{ + switch( buttonNum ) { + case 0: + dialogResult = UIresult::APPLY; + break; + case 1: + dialogResult = UIresult::SAVE; + break; + case 2: + dialogResult = UIresult::RELOAD; + break; + } + //fprintf( stdout, "setExitDisposition(): value changed to %d\n", buttonNum ) ; +} + +//=== Dialog exit and event handling functions ===// + +bool TDEStringMatcher_UI::DialogEventHandler::eventFilter( TQObject *o, TQEvent *e ) +{ + /* + Configure to act like in the TQLineEdit widget, + thereby returning focus to corresponding item in the TQListBox widget. + */ + if ( e->type() == TQEvent::KeyPress ) { + // special processing for key press + TQKeyEvent *k = (TQKeyEvent *)e; + + if ( k->key() == TQt::Key_Return || k->key() == TQt::Key_Enter ) { + TQKeyEvent key(TQEvent::KeyPress, TQt::Key_Tab, TQt::SHIFT , 0, 0, true ); + TQApplication::sendEvent(o, &key); + return true; + } + } + // standard event processing + return false; +} + +bool TDEStringMatcher_UI::event( TQEvent * e ) { + /* + Configure to exit dialog normally regardless of current + widget focus. User-selected dialogResult will be available to caller + as the real dialog return code. + */ + if ( e->type() != TQEvent::KeyPress ) { + TQKeyEvent * ke = (TQKeyEvent*) e; + if ( ke->key() == Key_Return && ke->state() == TQt::ControlButton ) { + ke->accept(); + accept() ; //exitOK(); + return true; + } + /* + already terminates the dialog regardless of current widget + focus. Therefore we don't need to do this: + if ( ke->key() == Key_Escape ) { + ke->accept(); + reject() ; //exitCancel(); + return true; + } + */ + } + return TQWidget::event( e ); +} + +void TDEStringMatcher_UI::accept() +{ + /* Exit dialog "normally" with dialogResult as the actual return code*/ + done(1); +} + + +void TDEStringMatcher_UI::reject() +{ + /* Exit dialog prematurely */ + dialogResult = UIresult::NOCHANGE; + done(0); +} + +//=== Dialog data retrieval functions ===// + +UIresult TDEStringMatcher_UI::getDialogResult() +{ + return dialogResult ; +} + +TDEStringMatcher::MatchSpecList& TDEStringMatcher_UI::getMatchSpecs() +{ + return matchSpecs ; +} + +#include "update_tdestringmatcher_dialog.moc" diff --git a/libkonq/update_tdestringmatcher_dialog.h b/libkonq/update_tdestringmatcher_dialog.h new file mode 100644 index 000000000..042542e7c --- /dev/null +++ b/libkonq/update_tdestringmatcher_dialog.h @@ -0,0 +1,118 @@ +#ifndef TDESTRINGMATCHER_DIALOG_H +#define TDESTRINGMATCHER_DIALOG_H + +#include +#include + +#include +#include "update_tdestringmatcher.h" + +class TQDialog; +class TQBoxLayout; +class TQVBoxLayout; +class TQHBoxLayout; +class TQGroupBox; +class TQButtonGroup; +class TQSpacerItem; +class TQLabel; +class TQListBox; +class TQListBoxItem; +class TQLineEdit; +class TQComboBox; +class TQPushButton; +class TQRadioButton; + +class TDEStringMatcher_UI : public TQDialog +{ + TQ_OBJECT + +public: + + TDEStringMatcher_UI( + TDEStringMatcher::MatchSpecList& data, + TQString title = "" + ); + ~TDEStringMatcher_UI(); + + UIresult getDialogResult(); + TDEStringMatcher::MatchSpecList& getMatchSpecs(); + +public slots: + +protected slots: + + virtual void displayItemText(); + virtual void editItemText(); + virtual void updateItemText(); + virtual void lineEditReturn(); + virtual void addItem(); + virtual void removeItem(); + + virtual void updatePatternType(int index ); + virtual void updateANCHandling(int index ); + virtual void updateWantMatch(int index ); + + virtual void setExitDisposition(int buttonNum ); + + virtual void accept(); + virtual void reject(); + +protected: + + // Keyboard event handlers + + bool event( TQEvent * e ); + class DialogEventHandler : public TQObject + { + protected: + bool eventFilter( TQObject *o, TQEvent *e ); + }; + + // Internal data + + TDEStringMatcher::MatchSpecList matchSpecs; + UIresult dialogResult; + + // Primary widgets + + TQLabel *patterns_label; + TQLabel *lbl_patternListHeader; + + TQListBox* lb_patternList; + TQLineEdit* le_editPattern; + + TQPushButton* pb_addPattern; + TQPushButton* pb_delPattern; + + TQComboBox* cb_patternType; + TQComboBox* cb_ancHandling; + TQComboBox* cb_expectMatch; + + TQButtonGroup *bg_Disposition; + TQRadioButton *rb_ApplyNoSave; + TQRadioButton *rb_ApplyAndSave; + TQRadioButton *rb_RestoreDefault; + + TQPushButton *pb_OK; + TQPushButton *pb_Cancel; + + // Layout, grouping, and spacing widgets + + TQVBoxLayout* main_vbl; + + TQHBoxLayout* sec1X_hbl; + TQVBoxLayout* sec1A_vbl; + + TQBoxLayout* sec1B_vbl; + TQGroupBox* sec1B1_vbx; + TQVBoxLayout *sec1B1_vbl; + TQGroupBox *sec1B2_vbx; + TQVBoxLayout *sec1B2_vbl; + TQSpacerItem* pad1B3; + TQVBoxLayout *sec1B4_vbl; + + TQHBoxLayout* sec2X_hbl; + TQSpacerItem* pad2_hb; +}; + +#endif