You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdenetwork/filesharing/advanced/kcm_sambaconf/hiddenfileview.cpp

611 lines
18 KiB

/***************************************************************************
hiddenfileview.cpp - description
-------------------
begin : Wed Jan 1 2003
copyright : (C) 2003 by Jan Sch<63>er
email : janschaefer@users.sourceforge.net
***************************************************************************/
/******************************************************************************
* *
* This file is part of KSambaPlugin. *
* *
* KSambaPlugin is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* KSambaPlugin is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with KSambaPlugin; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
* *
******************************************************************************/
#include <assert.h>
#include <tqcheckbox.h>
#include <tqlineedit.h>
#include <tqregexp.h>
#include <tqstringlist.h>
#include <tqgroupbox.h>
#include <tqcursor.h>
#include <kpopupmenu.h>
#include <kaction.h>
#include <krestrictedline.h>
#include <klocale.h>
#include <kfiledetailview.h>
#include <kdirlister.h>
#include <kmessagebox.h>
#include <kurlrequester.h>
#include "hiddenfileview.h"
#include "sharedlgimpl.h"
#include "sambashare.h"
#define COL_NAME 0
#define COL_HIDDEN 1
#define COL_VETO 2
#define COL_VETO_OPLOCK 3
#define COL_SIZE 4
#define COL_DATE 5
#define COL_PERM 6
#define COL_OWNER 7
#define COL_GROUP 8
#define HIDDENTABINDEX 5
HiddenListViewItem::HiddenListViewItem( TQListView *tqparent, KFileItem *fi, bool hidden=false, bool veto=false, bool vetoOplock=false )
: QMultiCheckListItem( tqparent )
{
setPixmap( COL_NAME, fi->pixmap(KIcon::SizeSmall));
setText( COL_NAME, fi->text() );
setText( COL_SIZE, KGlobal::locale()->formatNumber( fi->size(), 0));
setText( COL_DATE, fi->timeString() );
setText( COL_PERM, fi->permissionsString() );
setText( COL_OWNER, fi->user() );
setText( COL_GROUP, fi->group() );
setOn(COL_HIDDEN,hidden);
setOn(COL_VETO,veto);
setOn(COL_VETO_OPLOCK,vetoOplock);
_fileItem = fi;
}
HiddenListViewItem::~HiddenListViewItem()
{
}
KFileItem* HiddenListViewItem::getFileItem()
{
return _fileItem;
}
void HiddenListViewItem::paintCell(TQPainter *p, const TQColorGroup &cg, int column, int width, int tqalignment)
{
TQColorGroup _cg = cg;
if (isOn(COL_VETO))
_cg.setColor(TQColorGroup::Base,lightGray);
if (isOn(COL_HIDDEN))
_cg.setColor(TQColorGroup::Text,gray);
QMultiCheckListItem::paintCell(p, _cg, column, width, tqalignment);
}
HiddenFileView::HiddenFileView(ShareDlgImpl* shareDlg, SambaShare* share)
{
_share = share;
_dlg = shareDlg;
_hiddenActn = new KToggleAction(i18n("&Hide"));
_vetoActn = new KToggleAction(i18n("&Veto"));
_vetoOplockActn = new KToggleAction(i18n("&Veto Oplock"));
initListView();
_dlg->hiddenChk->setTristate(true);
_dlg->vetoChk->setTristate(true);
connect( _dlg->hiddenChk, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT( hiddenChkClicked(bool) ));
connect( _dlg->vetoChk, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT( vetoChkClicked(bool) ));
connect( _dlg->vetoOplockChk, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT( vetoOplockChkClicked(bool) ));
_dlg->hiddenEdit->setText( _share->getValue("hide files") );
connect( _dlg->hiddenEdit, TQT_SIGNAL(textChanged(const TQString &)), this, TQT_SLOT(updateView()));
_dlg->vetoEdit->setText( _share->getValue("veto files") );
connect( _dlg->vetoEdit, TQT_SIGNAL(textChanged(const TQString &)), this, TQT_SLOT(updateView()));
_dlg->vetoOplockEdit->setText( _share->getValue("veto oplock files") );
connect( _dlg->vetoOplockEdit, TQT_SIGNAL(textChanged(const TQString &)), this, TQT_SLOT(updateView()));
// new TQLabel(i18n("Hint")+" : ",grid);
// new TQLabel(i18n("You have to separate the entries with a '/'. You can use the wildcards '*' and '?'"),grid);
// new TQLabel(i18n("Example")+" : ",grid);
// new TQLabel(i18n("*.tmp/*SECRET*/.*/file?.*/"),grid);
_dir = new KDirLister(true);
_dir->setShowingDotFiles(true);
connect( _dir, TQT_SIGNAL(newItems(const KFileItemList &)),
this, TQT_SLOT(insertNewFiles(const KFileItemList &)));
connect( _dir, TQT_SIGNAL(deleteItem(KFileItem*)),
this, TQT_SLOT(deleteItem(KFileItem*)));
connect( _dir, TQT_SIGNAL(refreshItems(const KFileItemList &)),
this, TQT_SLOT(refreshItems(const KFileItemList &)));
connect( _hiddenActn, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(hiddenChkClicked(bool)));
connect( _vetoActn, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(vetoChkClicked(bool)));
connect( _vetoOplockActn, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(vetoOplockChkClicked(bool)));
}
void HiddenFileView::initListView()
{
_dlg->hiddenListView->setMultiSelection(true);
_dlg->hiddenListView->setSelectionMode(TQListView::Extended);
_dlg->hiddenListView->setAllColumnsShowFocus(true);
_hiddenList = createRegExpList(_share->getValue("hide files"));
_vetoList = createRegExpList(_share->getValue("veto files"));
_vetoOplockList = createRegExpList(_share->getValue("veto oplock files"));
_popup = new KPopupMenu(_dlg->hiddenListView);
_hiddenActn->plug(_popup);
_vetoActn->plug(_popup);
_vetoOplockActn->plug(_popup);
connect( _dlg->hiddenListView, TQT_SIGNAL(selectionChanged()), this, TQT_SLOT(selectionChanged()));
connect( _dlg->hiddenListView, TQT_SIGNAL(contextMenu(KListView*,TQListViewItem*,const TQPoint&)),
this, TQT_SLOT(showContextMenu()));
connect( _dlg->hideDotFilesChk, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(hideDotFilesChkClicked(bool)));
connect( _dlg->hideUnreadableChk, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(hideUnreadableChkClicked(bool)));
connect( _dlg->hiddenListView, TQT_SIGNAL(mouseButtonPressed(int,TQListViewItem*,const TQPoint &,int)),
this, TQT_SLOT(slotMouseButtonPressed(int,TQListViewItem*,const TQPoint &,int)));
}
HiddenFileView::~HiddenFileView()
{
delete _dir;
}
void HiddenFileView::load()
{
if (_dlg->hiddenListView)
_dlg->hiddenListView->clear();
_dir->openURL( _dlg->pathUrlRq->url() );
}
void HiddenFileView::save()
{
TQString s = _dlg->hiddenEdit->text().stripWhiteSpace();
// its important that the string ends with an '/'
// otherwise Samba won't recognize the last entry
if ( (!s.isEmpty()) && (s.right(1)!="/"))
s+="/";
_share->setValue("hide files", s);
s = _dlg->vetoEdit->text().stripWhiteSpace();
// its important that the string ends with an '/'
// otherwise Samba won't recognize the last entry
if ( (!s.isEmpty()) && (s.right(1)!="/"))
s+="/";
_share->setValue("veto files", s);
s = _dlg->vetoOplockEdit->text().stripWhiteSpace();
// its important that the string ends with an '/'
// otherwise Samba won't recognize the last entry
if ( (!s.isEmpty()) && (s.right(1)!="/"))
s+="/";
_share->setValue("veto oplock files", s);
}
void HiddenFileView::insertNewFiles(const KFileItemList &newone)
{
if ( newone.isEmpty() )
return;
KFileItem *tmp;
int j=0;
for (KFileItemListIterator it(newone); (tmp = it.current()); ++it)
{
j++;
bool hidden = matchHidden(tmp->text());
bool veto = matchVeto(tmp->text());
bool vetoOplock = matchVetoOplock(tmp->text());
new HiddenListViewItem( _dlg->hiddenListView, tmp, hidden, veto, vetoOplock );
}
}
void HiddenFileView::columnClicked(int column) {
switch (column) {
case COL_HIDDEN : hiddenChkClicked( !_dlg->hiddenChk->isOn() );break;
case COL_VETO : vetoChkClicked( !_dlg->vetoChk->isOn() );break;
case COL_VETO_OPLOCK : vetoOplockChkClicked( !_dlg->vetoOplockChk->isOn() );break;
default : break;
}
}
void HiddenFileView::deleteItem( KFileItem *fileItem )
{
HiddenListViewItem* item;
for (item = dynamic_cast<HiddenListViewItem*>(_dlg->hiddenListView->firstChild());item;
item = dynamic_cast<HiddenListViewItem*>(item->nextSibling()))
{
if (item->getFileItem() == fileItem)
{
delete item;
break;
}
}
}
void HiddenFileView::refreshItems( const KFileItemList& /*items*/ )
{
updateView();
}
void HiddenFileView::showContextMenu()
{
_popup->exec(TQCursor::pos());
}
void HiddenFileView::selectionChanged()
{
bool veto = false;
bool noVeto = false;
bool hide = false;
bool noHide = false;
bool vetoOplock = false;
bool noVetoOplock = false;
int n = 0;
HiddenListViewItem* item;
for (item = static_cast<HiddenListViewItem*>(_dlg->hiddenListView->firstChild());item;
item = static_cast<HiddenListViewItem*>(item->nextSibling()))
{
if (!item->isSelected())
continue;
n++;
if (item->isOn(COL_VETO))
veto = true;
else
noVeto = true;
if (item->isOn(COL_VETO_OPLOCK))
vetoOplock = true;
else
noVetoOplock = true;
if (item->isOn(COL_HIDDEN))
hide = true;
else
noHide = true;
}
_dlg->selGrpBx->setEnabled(n>0);
if (veto && noVeto)
{
_dlg->vetoChk->setTristate(true);
_dlg->vetoChk->setNoChange();
_dlg->vetoChk->update();
}
else
{
_dlg->vetoChk->setTristate(false);
_dlg->vetoChk->setChecked(veto);
}
if (vetoOplock && noVetoOplock)
{
_dlg->vetoOplockChk->setTristate(true);
_dlg->vetoOplockChk->setNoChange();
_dlg->vetoOplockChk->update();
}
else
{
_dlg->vetoOplockChk->setTristate(false);
_dlg->vetoOplockChk->setChecked(vetoOplock);
}
if (hide && noHide)
{
_dlg->hiddenChk->setTristate(true);
_dlg->hiddenChk->setNoChange();
_dlg->hiddenChk->update();
}
else
{
_dlg->hiddenChk->setTristate(false);
_dlg->hiddenChk->setChecked(hide);
}
}
void HiddenFileView::checkBoxClicked(TQCheckBox* chkBox,KToggleAction* action,TQLineEdit* edit, int column,TQPtrList<TQRegExp> & reqExpList,bool b) {
// We don't save the old state so
// disable the tristate mode
chkBox->setTristate(false);
action->setChecked(b);
chkBox->setChecked(b);
HiddenListViewItem* item;
for (item = static_cast<HiddenListViewItem*>(_dlg->hiddenListView->firstChild());item;
item = static_cast<HiddenListViewItem*>(item->nextSibling()))
{
if (!item->isSelected())
continue;
if (b == item->isOn(column))
continue;
if (!b) {
TQRegExp* rx = getRegExpListMatch(item->text(0),reqExpList);
// Perhaps the file was hidden because it started with a dot
if (!rx && item->text(0)[0]=='.' && _dlg->hideDotFilesChk->isChecked()) {
int result = KMessageBox::questionYesNo(_dlg,i18n(
"<qt>Some files you have selected are hidden because they start with a dot; "
"do you want to uncheck all files starting with a dot?</qt>"),i18n("Files Starting With Dot"),i18n("Uncheck Hidden"), i18n("Keep Hidden"));
if (result == KMessageBox::No) {
TQPtrList<HiddenListViewItem> lst = getMatchingItems(TQRegExp(".*",false,true));
deselect(lst);
} else {
_dlg->hideDotFilesChk->setChecked(false);
}
continue;
} else {
if (rx) {
// perhaps it is matched by a wildcard string
TQString p = rx->pattern();
if ( p.tqfind("*") > -1 ||
p.tqfind("?") > -1 )
{
// TODO after message freeze: why show three times the wildcard string? Once should be enough.
// TODO remove <b></b> and use <qt> instead
int result = KMessageBox::questionYesNo(_dlg,i18n(
"<b></b>Some files you have selected are matched by the wildcarded string <b>'%1'</b>; "
"do you want to uncheck all files matching <b>'%1'</b>?").tqarg(rx->pattern()).tqarg(rx->pattern()).tqarg(rx->pattern()),
i18n("Wildcarded String"),i18n("Uncheck Matches"),i18n("Keep Selected"));
TQPtrList<HiddenListViewItem> lst = getMatchingItems( *rx );
if (result == KMessageBox::No) {
deselect(lst);
} else {
setState(lst,column,false);
reqExpList.remove(rx);
updateEdit(edit, reqExpList);
}
continue;
} else {
reqExpList.remove(rx);
updateEdit(edit, reqExpList);
}
}
}
}
else {
reqExpList.append( new TQRegExp(item->text(0)) );
updateEdit(edit, reqExpList);
}
item->setOn(column,b);
}
_dlg->hiddenListView->update();
}
void HiddenFileView::hiddenChkClicked(bool b)
{
checkBoxClicked(_dlg->hiddenChk, _hiddenActn, _dlg->hiddenEdit, COL_HIDDEN,_hiddenList,b);
}
void HiddenFileView::vetoOplockChkClicked(bool b) {
checkBoxClicked(_dlg->vetoOplockChk, _vetoOplockActn, _dlg->vetoOplockEdit, COL_VETO_OPLOCK,_vetoOplockList,b);
}
void HiddenFileView::vetoChkClicked(bool b)
{
checkBoxClicked(_dlg->vetoChk, _vetoActn, _dlg->vetoEdit, COL_VETO,_vetoList,b);
}
/**
* Sets the text of the TQLineEdit edit to the entries of the passed TQRegExp-List
**/
void HiddenFileView::updateEdit(TQLineEdit* edit, TQPtrList<TQRegExp> & lst)
{
TQString s="";
TQRegExp* rx;
for(rx = static_cast<TQRegExp*>(lst.first()); rx;
rx = static_cast<TQRegExp*>(lst.next()) )
{
s+= rx->pattern()+TQString("/");
}
edit->setText(s);
}
void HiddenFileView::setState(TQPtrList<HiddenListViewItem> & lst, int column, bool b) {
HiddenListViewItem* item;
for(item = static_cast<HiddenListViewItem*>(lst.first()); item;
item = static_cast<HiddenListViewItem*>(lst.next()) )
{
item->setOn(column,b);
}
}
void HiddenFileView::deselect(TQPtrList<HiddenListViewItem> & lst)
{
HiddenListViewItem* item;
for(item = static_cast<HiddenListViewItem*>(lst.first()); item;
item = static_cast<HiddenListViewItem*>(lst.next()) )
{
item->setSelected(false);
}
}
TQPtrList<HiddenListViewItem> HiddenFileView::getMatchingItems(const TQRegExp & rx)
{
TQPtrList<HiddenListViewItem> lst;
HiddenListViewItem* item;
for (item = static_cast<HiddenListViewItem*>(_dlg->hiddenListView->firstChild());item;
item = static_cast<HiddenListViewItem*>(item->nextSibling()))
{
if (rx.exactMatch(item->text(0)))
lst.append(item);
}
return lst;
}
void HiddenFileView::updateView()
{
_hiddenList = createRegExpList(_dlg->hiddenEdit->text());
_vetoList = createRegExpList(_dlg->vetoEdit->text());
_vetoOplockList = createRegExpList(_dlg->vetoOplockEdit->text());
HiddenListViewItem* item;
for (item = static_cast<HiddenListViewItem*>(_dlg->hiddenListView->firstChild());item;
item = static_cast<HiddenListViewItem*>(item->nextSibling()))
{
item->setOn(COL_HIDDEN,matchHidden(item->text(0)));
item->setOn(COL_VETO,matchVeto(item->text(0)));
item->setOn(COL_VETO_OPLOCK,matchVetoOplock(item->text(0)));
}
_dlg->hiddenListView->tqrepaint();
}
TQPtrList<TQRegExp> HiddenFileView::createRegExpList(const TQString & s)
{
TQPtrList<TQRegExp> lst;
bool cs = _share->getBoolValue("case sensitive");
if (!s.isEmpty())
{
TQStringList l = TQStringList::split("/",s);
for ( TQStringList::Iterator it = l.begin(); it != l.end(); ++it ) {
lst.append( new TQRegExp(*it,cs,true) );
}
}
return lst;
}
bool HiddenFileView::matchHidden(const TQString & s)
{
TQPtrList<TQRegExp> hiddenList(_hiddenList);
if (_dlg->hideDotFilesChk->isChecked())
hiddenList.append( new TQRegExp(".*",false,true) );
return matchRegExpList(s,hiddenList);
}
bool HiddenFileView::matchVeto(const TQString & s)
{
return matchRegExpList(s,_vetoList);
}
bool HiddenFileView::matchVetoOplock(const TQString & s)
{
return matchRegExpList(s,_vetoOplockList);
}
bool HiddenFileView::matchRegExpList(const TQString & s, TQPtrList<TQRegExp> & lst)
{
if (getRegExpListMatch(s,lst))
return true;
else
return false;
}
TQRegExp* HiddenFileView::getHiddenMatch(const TQString & s)
{
return getRegExpListMatch(s,_hiddenList);
}
TQRegExp* HiddenFileView::getVetoMatch(const TQString & s)
{
return getRegExpListMatch(s,_vetoList);
}
TQRegExp* HiddenFileView::getRegExpListMatch(const TQString & s, TQPtrList<TQRegExp> & lst)
{
TQRegExp* rx;
for ( rx = lst.first(); rx; rx = lst.next() )
{
if (rx->exactMatch(s))
return rx;
}
return 0L;
}
void HiddenFileView::hideDotFilesChkClicked(bool)
{
updateView();
}
void HiddenFileView::hideUnreadableChkClicked(bool)
{
updateView();
}
void HiddenFileView::slotMouseButtonPressed( int, TQListViewItem*, const TQPoint&, int c ) {
columnClicked(c);
}
#include "hiddenfileview.moc"