expander.cpp
来自「LINUX 下, 以 QT/KDE 写的档案管理员」· C++ 代码 · 共 1,225 行 · 第 1/3 页
CPP
1,225 行
/* from Panel/krview.h: enum SortSpec { Name=0x1, Ext=0x2, Size=0x4, Type=0x8, Modified=0x10, Permissions=0x20, KrPermissions=0x40, Owner=0x80, Group=0x100, Descending=0x200, DirsFirst=0x400, IgnoreCase=0x800 }; */ // krOut << "start: exp_ColSort::expFunc" << endl; #define MODE_OUT krOut << QString( "mode: %1" ).arg( mode, 0, 2 ) << endl; // displays mode in base-2 //MODE_OUT if ( parameter.count() <= 1 || ( parameter[1].lower() != "asc" && parameter[1].lower() != "desc" ) ) { //default == toggle if ( mode & KrViewProperties::Descending ) mode &= ~KrViewProperties::Descending; // == asc else mode |= KrViewProperties::Descending; // == desc } else if ( parameter[1].lower() == "asc" ) { mode &= ~KrViewProperties::Descending; } else { // == desc mode |= KrViewProperties::Descending; } //MODE_OUT // clear all column-infromation: mode &= ~( KrViewProperties::Name | KrViewProperties::Ext | KrViewProperties::Size | KrViewProperties::Type | KrViewProperties::Modified | KrViewProperties::Permissions | KrViewProperties::KrPermissions | KrViewProperties::Owner | KrViewProperties::Group ); MODE_OUT if ( parameter[0].lower() == "name" ) { mode |= KrViewProperties::Name; } else if ( parameter[0].lower() == "ext" ) { mode |= KrViewProperties::Ext; } else if ( parameter[0].lower() == "type" ) { mode |= KrViewProperties::Type; } else if ( parameter[0].lower() == "size" ) { mode |= KrViewProperties::Size; } else if ( parameter[0].lower() == "modified" ) { mode |= KrViewProperties::Modified; } else if ( parameter[0].lower() == "perms" ) { mode |= KrViewProperties::Permissions; } else if ( parameter[0].lower() == "rwx" ) { mode |= KrViewProperties::KrPermissions; } else if ( parameter[0].lower() == "owner" ) { mode |= KrViewProperties::Owner; } else if ( parameter[0].lower() == "group" ) { mode |= KrViewProperties::Group; } else { setError(exp, Error(Error::S_WARNING,Error::C_ARGUMENT,i18n("Expander: unknown column specified for %_ColSort(%1)%").arg(parameter[0]) )); return QString::null; } //MODE_OUT panel->view->setSortMode( (KrViewProperties::SortSpec)mode );// krOut << "end: exp_ColSort::expFunc" << endl; return QString::null; // this doesn't return anything, that's normal!}exp_PanelSize::exp_PanelSize() { _expression = "PanelSize"; _description = i18n("Set Relation Between the Panels..."); _needPanel = true; addParameter( exp_parameter( i18n("Set the new size in percent:"), "__int:0;100;5;50", true ) );}TagString exp_PanelSize::expFunc( const ListPanel* panel, const QStringList& parameter, const bool&, Expander& exp ) const { NEED_PANEL int newSize; if ( parameter[0].isEmpty() ) newSize = 50; //default is 50% else newSize = parameter[0].toInt(); if ( newSize < 0 || newSize > 100 ) { setError(exp, Error(Error::S_FATAL,Error::C_ARGUMENT,i18n("Expander: Value %1 out of range for %_PanelSize(percent)%. The first parameter has to be >0 and <100").arg(newSize)) ); return QString::null; } QValueList<int> panelSizes = MAIN_VIEW->horiz_splitter->sizes(); int totalSize = panelSizes[0] + panelSizes[1]; if ( panel == LEFT_PANEL ) { panelSizes[0] = totalSize * newSize / 100; panelSizes[1] = totalSize * (100 - newSize) / 100; } else { // == RIGHT_PANEL panelSizes[0] = totalSize * (100 - newSize) / 100; panelSizes[1] = totalSize * newSize / 100; } MAIN_VIEW->horiz_splitter->setSizes( panelSizes ); return QString::null; // this doesn't return everything, that's normal!}#ifdef __KJSEMBED__exp_Script::exp_Script() { _expression = "Script"; _description = i18n("Execute a JavaScript Extension..."); _needPanel = false; addParameter( exp_parameter( i18n("Location of the script"), "", true ) ); addParameter( exp_parameter( i18n("Set some variables for the execution (optional).\ni.e. \"return=return_var;foo=bar\", consult the handbook for more information"), "", false ) );}TagString exp_Script::expFunc( const ListPanel*, const QStringList& parameter, const bool&, Expander& exp ) const { if ( parameter[0].isEmpty() ) { setError(exp, Error(Error::S_FATAL,Error::C_ARGUMENT,i18n("Expander: no script specified for %_Script(script)%")) ); return QString::null; } QString filename = parameter[0]; if ( filename.find('/') && KURL::isRelativeURL(filename) ) { // this return the local version of the file if this exists. else the global one is returnd filename = locate( "data", "krusader/js/"+filename ); } if ( ! krJS ) krJS = new KrJS(); KJS::ExecState *exec = krJS->globalExec(); QString jsReturn = QString::null; if ( parameter[1].lower() == "yes" ) // to stay compatible with the old-style parameter jsReturn = "cmd"; else { QStringList jsVariables = QStringList::split( ';', parameter[1] ); QString jsVariable, jsValue; for ( QStringList::Iterator it = jsVariables.begin(); it != jsVariables.end(); ++it ) { jsVariable = (*it).section('=', 0, 0).stripWhiteSpace(); jsValue = (*it).section('=', 1); if ( jsVariable == "return" ) jsReturn = jsValue.stripWhiteSpace(); else krJS->putValue( jsVariable, KJSEmbed::convertToValue(exec, jsValue ) ); } } krJS->runFile( filename ); if ( ! jsReturn.isEmpty() ) return krJS->getValue( jsReturn ).toString( krJS->globalExec() ).qstring(); else return QString::null;}#endifexp_View::exp_View() { _expression = "View"; _description = i18n("View File with Krusader's Internal Viewer..."); _needPanel = false; addParameter( exp_parameter( i18n("Which file to view (normally '%aCurrent%'):"), "__placeholder", true ) ); addParameter( exp_parameter( i18n("Choose a view mode:"), "__choose:generic;text;hex", false ) ); //addParameter( exp_parameter( i18n("Choose a window-mode"), "__choose:tab;window;panel", false ) ); //TODO: window-mode 'panel' should open the file in the third-hand viewer addParameter( exp_parameter( i18n("Choose a window mode:"), "__choose:tab;window", false ) );}TagString exp_View::expFunc( const ListPanel*, const QStringList& parameter, const bool&, Expander& exp ) const { if ( parameter[0].isEmpty() ) { setError(exp, Error(Error::S_FATAL,Error::C_ARGUMENT,i18n("Expander: no file to view in %_View(filename)%")) ); return QString::null; } QString viewMode, windowMode; if ( parameter.count() <= 1 || parameter[1].isEmpty() ) viewMode = "generic"; else viewMode = parameter[1]; if ( parameter.count() <= 2 || parameter[2].isEmpty() ) windowMode = "tab"; else windowMode = parameter[2]; KrViewer::Mode mode = KrViewer::Generic; if( viewMode == "text" ) mode = KrViewer::Text; else if( viewMode == "hex" ) mode = KrViewer::Hex; KrViewer::view(parameter[0],mode,(windowMode == "window")); //TODO: Call the viewer with viewMode and windowMode. Filename is in parameter[0]. // It would be nice if parameter[0] could also be a space-separated filename-list (provided if the first parameter is %aList(selected)%) return QString::null; // this doesn't return everything, that's normal!}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// end of expander classes /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////TagString exp_simpleplaceholder::expFunc( const ListPanel* p, const TagStringList& parameter, const bool& useUrl, Expander& exp) const { QStringList lst; for(TagStringList::const_iterator it=parameter.begin(),end=parameter.end();it!=end;++it) if((*it).isSimple()) lst.push_back((*it).string()); else { setError(exp,Error(Error::S_FATAL,Error::C_SYNTAX,i18n("%Each% is not allowed in parameter to %1").arg(description()))); return QString::null; } return expFunc(p,lst,useUrl,exp);}}ListPanel* Expander::getPanel( const char panelIndicator, const exp_placeholder* pl, Expander& exp ) { switch ( panelIndicator ) { case 'a': return ACTIVE_PANEL; case 'o': return OTHER_PANEL; case 'l': return LEFT_PANEL; case 'r': return RIGHT_PANEL; case '_': return 0; default: exp.setError(Error(Error::S_FATAL,Error::C_SYNTAX,i18n("Expander: Bad panel specifier %1 in placeholder %2").arg(panelIndicator).arg(pl->description()))); return 0; }}void Expander::expand( const QString& stringToExpand, bool useUrl ) { TagString result = expandCurrent( stringToExpand, useUrl ); if ( error() ) return; if ( !result.isSimple() ) resultList = splitEach( result ); else resultList.append( result.string() );// krOut << resultList[0] << endl;}TagString Expander::expandCurrent( const QString& stringToExpand, bool useUrl ) { TagString result; QString exp = QString::null; TagString tmpResult; int begin, end, i;// int brackets = 0;// bool inQuotes = false; unsigned int idx = 0; while ( idx < stringToExpand.length() ) { if ( ( begin = stringToExpand.find( '%', idx ) ) == -1 ) break; if ( ( end = findEnd( stringToExpand, begin ) ) == -1 ) { setError(Error(Error::S_FATAL,Error::C_SYNTAX,i18n("Error: unterminated % in Expander::expandCurrent")) ); return QString::null; } result += stringToExpand.mid( idx, begin - idx ); // copy until the start of %exp% // get the expression, and expand it using the correct expander function exp = stringToExpand.mid( begin + 1, end - begin - 1 );// kdDebug() << "------------- exp: '" << exp << "'" << endl; if ( exp == "" ) result += QString(QChar('%')); else { TagStringList parameter = separateParameter( &exp, useUrl ); if ( error() ) return QString::null; char panelIndicator = exp.lower()[0].latin1(); exp.replace( 0, 1, "" ); for ( i = 0; i < placeholderCount(); ++i ) if ( exp == placeholder( i )->expression() ) {// kdDebug() << "---------------------------------------" << endl; tmpResult = placeholder( i )->expFunc( getPanel( panelIndicator,placeholder(i),*this ), parameter, useUrl, *this ); if ( error() ) { return QString::null; } else result += tmpResult;// kdDebug() << "---------------------------------------" << endl; break; } if ( i == placeholderCount() ) { // didn't find an expander setError(Error(Error::S_FATAL,Error::C_SYNTAX,i18n("Error: unrecognized %%%1%2%% in Expander::expand").arg(panelIndicator).arg(exp)) ); return QString::null; } } //else idx = end + 1; } // copy the rest of the string result += stringToExpand.mid( idx );// kdDebug() << "============== result '" << result << "'" << endl; return result;}QStringList Expander::splitEach( TagString stringToSplit ) { if(stringToSplit.isSimple()) {// krOut << stringToSplit.string() << endl; return stringToSplit.string(); } pair<uint,QStringList> pl=*stringToSplit.tagsBegin(); stringToSplit.eraseTag(stringToSplit.tagsBegin()); QStringList ret; for(QStringList::const_iterator it=pl.second.begin(),end=pl.second.end();it!=end;++it) { TagString s=stringToSplit; s.insert(pl.first,*it); ret+=splitEach(s); } return ret;// kdDebug() << "stringToSplit: " << stringToSplit << endl;}TagStringList Expander::separateParameter( QString* const exp, bool useUrl ) { TagStringList parameter; QStringList parameter1; QString result; int begin, end; if ( ( begin = exp->find( '(' ) ) != -1 ) { if ( ( end = exp->findRev( ')' ) ) == -1 ) { setError(Error(Error::S_FATAL,Error::C_SYNTAX,i18n("Error: missing ')' in Expander::separateParameter") )); return TagStringList(); } result = exp->mid( begin + 1, end - begin - 1 ); *exp = exp->left( begin ); bool inQuotes = false; unsigned int idx = 0; begin = 0; while ( idx < result.length() ) { if ( result[ idx ].latin1() == '\\' ) { if ( result[ idx+1 ].latin1() == '"') result.replace( idx, 1, "" ); } if ( result[ idx ].latin1() == '"' ) inQuotes = !inQuotes; if ( result[ idx ].latin1() == ',' && !inQuotes ) { parameter1.append( result.mid( begin, idx - begin) ); begin = idx + 1;// krOut << " ---- parameter: " << parameter.join(";") << endl; } idx++; } parameter1.append( result.mid( begin, idx - begin) ); //don't forget the last one for (QStringList::Iterator it = parameter1.begin(); it != parameter1.end(); ++it) { *it = (*it).stripWhiteSpace(); if ( (*it).left(1) == "\"" ) *it = (*it).mid(1, (*it).length() - 2 ); parameter.push_back(expandCurrent( *it, useUrl )); if ( error() ) return TagStringList(); } } // krOut << "------- exp: " << *exp << " ---- parameter: " << parameter.join(";") << endl; return parameter;}int Expander::findEnd( const QString& str, int start ) { int end = str.find( '%', start + 1 ); if ( end == -1 ) return end; int bracket = str.find( '(', start + 1 ); if ( end < bracket || bracket == -1 ) return end; unsigned int idx = bracket+1; bool inQuotes = false; int depth=1; while ( idx < str.length() ) { switch (str[ idx ].latin1()) { case '\\': idx ++; break; case '"': inQuotes = !inQuotes; break; case '(': if(!inQuotes) depth++; break; case ')': if(!inQuotes) --depth; break; case '%': if(depth==0) return idx; } //switch idx++; } //while // failsafe return -1;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?