void URLGrabber::matchingMimeActions(const QString& clipData) { KUrl url(clipData); KConfigGroup cg(KGlobal::config(), "Actions"); if(!cg.readEntry("EnableMagicMimeActions",true)) { //kDebug() << "skipping mime magic due to configuration"; return; } if(!url.isValid()) { //kDebug() << "skipping mime magic due to invalid url"; return; } if(url.isRelative()) { //openinng a relative path will just not work. what path should be used? //kDebug() << "skipping mime magic due to relative url"; return; } if(url.isLocalFile()) { if ( clipData == "//") { //kDebug() << "skipping mime magic due to C++ comment //"; return; } if(!QFile::exists(url.toLocalFile())) { //kDebug() << "skipping mime magic due to nonexistent localfile"; return; } } // try to figure out if clipData contains a filename KMimeType::Ptr mimetype = KMimeType::findByUrl( url, 0, false, true /*fast mode*/ ); // let's see if we found some reasonable mimetype. // If we do we'll populate menu with actions for apps // that can handle that mimetype // first: if clipboard contents starts with http, let's assume it's "text/html". // That is even if we've url like "http://www.kde.org/somescript.pl", we'll // still treat that as html page, because determining a mimetype using kio // might take a long time, and i want this function to be quick! if ( ( clipData.startsWith( QLatin1String("http://") ) || clipData.startsWith( QLatin1String("https://") ) ) && mimetype->name() != "text/html" ) { // use a fake path to create a mimetype that corresponds to "text/html" mimetype = KMimeType::findByPath( "/tmp/klipper.html", 0, true /*fast mode*/ ); } if ( !mimetype->isDefault() ) { ClipAction* action = new ClipAction( QString(), mimetype->comment() ); KService::List lst = KMimeTypeTrader::self()->query( mimetype->name(), "Application" ); foreach( const KService::Ptr &service, lst ) { QHash<QChar,QString> map; map.insert( 'i', "--icon " + service->icon() ); map.insert( 'c', service->name() ); QString exec = service->exec(); exec = KMacroExpander::expandMacros( exec, map ).trimmed(); action->addCommand( ClipCommand( exec, service->name(), true, service->icon() ) ); }
ClipCommandProcess::ClipCommandProcess(const ClipAction& action, const ClipCommand& command, const QString& clip, History* history, const HistoryItem* original_item) : KProcess(), m_history(history), m_historyItem(original_item), m_newhistoryItem() { QHash<QChar,QString> map; map.insert( 's', clip ); // support %u, %U (indicates url param(s)) and %f, %F (file param(s)) map.insert( 'u', clip ); map.insert( 'U', clip ); map.insert( 'f', clip ); map.insert( 'F', clip ); const QStringList matches = action.regExpMatches(); // support only %0 and the first 9 matches... const int numMatches = qMin(10, matches.count()); for ( int i = 0; i < numMatches; ++i ) { map.insert( QChar( '0' + i ), matches.at( i ) ); } setOutputChannelMode(OnlyStdoutChannel); setShellCommand(KMacroExpander::expandMacrosShellQuote( command.command, map ).trimmed()); connect(this, SIGNAL(finished(int,QProcess::ExitStatus)), SLOT(slotFinished(int,QProcess::ExitStatus))); if (command.output != ClipCommand::IGNORE) { connect(this, SIGNAL(readyRead()), SLOT(slotStdOutputAvailable())); } if (command.output != ClipCommand::REPLACE) { m_historyItem = 0L; // Don't replace } }
ActionList * ActionWidget::actionList() { Q3ListViewItem *item = listView->firstChild(); Q3ListViewItem *child = 0L; ClipAction *action = 0L; ActionList *list = new ActionList; list->setAutoDelete( true ); while ( item ) { action = new ClipAction( item->text( 0 ), item->text( 1 ) ); child = item->firstChild(); // add the commands while ( child ) { action->addCommand( child->text( 0 ), child->text( 1 ), true ); child = child->nextSibling(); } list->append( action ); item = item->nextSibling(); } return list; }
ActionWidget::ActionWidget( const ActionList *list, ConfigDialog* configWidget, QWidget *parent, const char *name ) : KVBox( parent ), advancedWidget( 0L ) { setObjectName(name); Q_ASSERT( list != 0L ); QLabel *lblAction = new QLabel( i18n("Action &list (right click to add/remove commands):"), this ); listView = new ListView( configWidget, this ); lblAction->setBuddy( listView ); listView->addColumn( i18n("Regular Expression (see http://doc.trolltech.com/qregexp.html#details)") ); listView->addColumn( i18n("Description") ); listView->setRenameable(0); listView->setRenameable(1); listView->setItemsRenameable( true ); listView->setItemsMovable( false ); // listView->setAcceptDrops( true ); // listView->setDropVisualizer( true ); // listView->setDragEnabled( true ); listView->setRootIsDecorated( true ); listView->setMultiSelection( false ); listView->setAllColumnsShowFocus( true ); listView->setSelectionMode( Q3ListView::Single ); connect( listView, SIGNAL(executed( Q3ListViewItem*, const QPoint&, int )), SLOT( slotItemChanged( Q3ListViewItem*, const QPoint& , int ) )); connect( listView, SIGNAL( selectionChanged ( Q3ListViewItem * )), SLOT(selectionChanged ( Q3ListViewItem * ))); connect(listView, SIGNAL(contextMenu(K3ListView *, Q3ListViewItem *, const QPoint&)), SLOT( slotContextMenu(K3ListView*, Q3ListViewItem*, const QPoint&))); ClipAction *action = 0L; ClipCommand *command = 0L; Q3ListViewItem *item = 0L; Q3ListViewItem *child = 0L; Q3ListViewItem *after = 0L; // QListView's default inserting really sucks ActionListIterator it( *list ); const QPixmap& doc = SmallIcon( "misc" ); const QPixmap& exec = SmallIcon( "exec" ); for ( action = it.current(); action; action = ++it ) { item = new Q3ListViewItem( listView, after, action->regExp(), action->description() ); item->setPixmap( 0, doc ); Q3PtrListIterator<ClipCommand> it2( action->commands() ); for ( command = it2.current(); command; command = ++it2 ) { child = new Q3ListViewItem( item, after, command->command, command->description); if ( command->pixmap.isEmpty() ) child->setPixmap( 0, exec ); else child->setPixmap( 0, SmallIcon( command->pixmap ) ); after = child; } after = item; } listView->setSorting( -1 ); // newly inserted items just append unsorted cbUseGUIRegExpEditor = new QCheckBox( i18n("&Use graphical editor for editing regular expressions" ), this ); if ( KServiceTypeTrader::self()->query("KRegExpEditor/KRegExpEditor").isEmpty() ) { cbUseGUIRegExpEditor->hide(); cbUseGUIRegExpEditor->setChecked( false ); } KHBox *box = new KHBox( this ); box->setSpacing( KDialog::spacingHint() ); QPushButton *button = new QPushButton( i18n("&Add Action"), box ); connect( button, SIGNAL( clicked() ), SLOT( slotAddAction() )); delActionButton = new QPushButton( i18n("&Delete Action"), box ); connect( delActionButton, SIGNAL( clicked() ), SLOT( slotDeleteAction() )); QLabel *label = new QLabel(i18n("Click on a highlighted item's column to change it. \"%s\" in a command will be replaced with the clipboard contents."), box); label->setAlignment( Qt::AlignLeft | Qt::AlignVCenter ); label->setWordWrap( true ); box->setStretchFactor( label, 5 ); box = new KHBox( this ); QPushButton *advanced = new QPushButton( i18n("Advanced..."), box ); advanced->setFixedSize( advanced->sizeHint() ); connect( advanced, SIGNAL( clicked() ), SLOT( slotAdvanced() )); (void) new QWidget( box ); // spacer delActionButton->setEnabled(listView->currentItem () !=0); }