kwin Library API Documentation

ruleswidget.cpp

00001 /*
00002  * Copyright (c) 2004 Lubos Lunak <l.lunak@kde.org>
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017  */
00018 
00019 #include "ruleswidget.h"
00020 
00021 #include <klineedit.h>
00022 #include <krestrictedline.h>
00023 #include <kcombobox.h>
00024 #include <qcheckbox.h>
00025 #include <kpushbutton.h>
00026 #include <qlabel.h>
00027 #include <kwinmodule.h>
00028 #include <klocale.h>
00029 #include <qregexp.h>
00030 #include <qwhatsthis.h>
00031 #include <assert.h>
00032 #include <kmessagebox.h>
00033 #include <qtabwidget.h>
00034 
00035 #include "../../rules.h"
00036 
00037 #include "detectwidget.h"
00038 
00039 namespace KWinInternal
00040 {
00041 
00042 #define SETUP( var, type ) \
00043     connect( enable_##var, SIGNAL( toggled( bool )), rule_##var, SLOT( setEnabled( bool ))); \
00044     connect( enable_##var, SIGNAL( toggled( bool )), this, SLOT( updateEnable##var())); \
00045     connect( rule_##var, SIGNAL( activated( int )), this, SLOT( updateEnable##var())); \
00046     QWhatsThis::add( enable_##var, enableDesc ); \
00047     QWhatsThis::add( rule_##var, type##RuleDesc );
00048 
00049 RulesWidget::RulesWidget( QWidget* parent, const char* name )
00050 : RulesWidgetBase( parent, name )
00051 , detect_dlg( NULL )
00052     {
00053     QString enableDesc =
00054         i18n( "Enable this checkbox to alter this window property for the specified window(s)." );
00055     QString setRuleDesc =
00056         i18n( "Specify how the window property should be affected:<ul>"
00057               "<li><em>Do Not Affect:</em> The window property will not be affected and therefore"
00058               " the default handling for it will be used. Specifying this will block more generic"
00059               " window settings from taking effect.</li>"
00060               "<li><em>Apply Initially:</em> The window property will be only set to the given value"
00061               " after the window is created. No further changes will be affected.</li>"
00062               "<li><em>Remember:</em> The value of the window property will be remembered and every time"
00063               " time the window is created, the last remembered value will be applied.</li>"
00064               "<li><em>Force:</em> The window property will be always forced to the given value.</li></ul>" );
00065     QString forceRuleDesc =
00066         i18n( "Specify how the window property should be affected:<ul>"
00067               "<li><em>Do Not Affect:</em> The window property will not be affected and therefore"
00068               " the default handling for it will be used. Specifying this will block more generic"
00069               " window settings from taking effect.</li>"
00070               "<li><em>Force:</em> The window property will be always forced to the given value.</li></ul>" );
00071     // window tabs have enable signals done in designer
00072     // geometry tab
00073     SETUP( position, set );
00074     SETUP( size, set );
00075     SETUP( desktop, set );
00076     SETUP( maximizehoriz, set );
00077     SETUP( maximizevert, set );
00078     SETUP( minimize, set );
00079     SETUP( shade, set );
00080     SETUP( fullscreen, set );
00081     SETUP( placement, force );
00082     // preferences tab
00083     SETUP( above, set );
00084     SETUP( below, set );
00085     SETUP( noborder, set );
00086     SETUP( skiptaskbar, set );
00087     SETUP( skippager, set );
00088     SETUP( acceptfocus, force );
00089     SETUP( closeable, force );
00090     SETUP( opacityactive, force );
00091     SETUP( opacityinactive, force );
00092     SETUP( shortcut, force );
00093     // workarounds tab
00094     SETUP( fsplevel, force );
00095     SETUP( moveresizemode, force );
00096     SETUP( type, force );
00097     SETUP( ignoreposition, force );
00098     SETUP( minsize, force );
00099     SETUP( maxsize, force );
00100     SETUP( strictgeometry, force );
00101     KWinModule module;
00102     int i;
00103     for( i = 1;
00104          i <= module.numberOfDesktops();
00105          ++i )
00106         desktop->insertItem( QString::number( i ).rightJustify( 2 ) + ":" + module.desktopName( i ));
00107     desktop->insertItem( i18n( "All Desktops" ));
00108     }
00109 
00110 #undef SETUP
00111 
00112 #define UPDATE_ENABLE_SLOT( var ) \
00113 void RulesWidget::updateEnable##var() \
00114     { \
00115     /* leave the label readable label_##var->setEnabled( enable_##var->isChecked() && rule_##var->currentItem() != 0 );*/ \
00116     var->setEnabled( enable_##var->isChecked() && rule_##var->currentItem() != 0 ); \
00117     }
00118 
00119 // geometry tab
00120 UPDATE_ENABLE_SLOT( position )
00121 UPDATE_ENABLE_SLOT( size )
00122 UPDATE_ENABLE_SLOT( desktop )
00123 UPDATE_ENABLE_SLOT( maximizehoriz )
00124 UPDATE_ENABLE_SLOT( maximizevert )
00125 UPDATE_ENABLE_SLOT( minimize )
00126 UPDATE_ENABLE_SLOT( shade )
00127 UPDATE_ENABLE_SLOT( fullscreen )
00128 UPDATE_ENABLE_SLOT( placement )
00129 // preferences tab
00130 UPDATE_ENABLE_SLOT( above )
00131 UPDATE_ENABLE_SLOT( below )
00132 UPDATE_ENABLE_SLOT( noborder )
00133 UPDATE_ENABLE_SLOT( skiptaskbar )
00134 UPDATE_ENABLE_SLOT( skippager )
00135 UPDATE_ENABLE_SLOT( acceptfocus )
00136 UPDATE_ENABLE_SLOT( closeable )
00137 UPDATE_ENABLE_SLOT( opacityactive )
00138 UPDATE_ENABLE_SLOT( opacityinactive )
00139 void RulesWidget::updateEnableshortcut()
00140     {
00141     shortcut->setEnabled( enable_shortcut->isChecked() && rule_shortcut->currentItem() != 0 );
00142     shortcut_edit->setEnabled( enable_shortcut->isChecked() && rule_shortcut->currentItem() != 0 );
00143     }
00144 // workarounds tab
00145 UPDATE_ENABLE_SLOT( fsplevel )
00146 UPDATE_ENABLE_SLOT( moveresizemode )
00147 UPDATE_ENABLE_SLOT( type )
00148 UPDATE_ENABLE_SLOT( ignoreposition )
00149 UPDATE_ENABLE_SLOT( minsize )
00150 UPDATE_ENABLE_SLOT( maxsize )
00151 UPDATE_ENABLE_SLOT( strictgeometry )
00152 
00153 #undef UPDATE_ENABLE_SLOT
00154 
00155 static const int set_rule_to_combo[] =
00156     {
00157     0, // Unused
00158     0, // Don't Affect
00159     3, // Force
00160     1, // Apply
00161     2, // Remember
00162     };
00163 
00164 static const Rules::SetRule combo_to_set_rule[] =
00165     {
00166     ( Rules::SetRule )Rules::DontAffect,
00167     ( Rules::SetRule )Rules::Apply,
00168     ( Rules::SetRule )Rules::Remember,
00169     ( Rules::SetRule )Rules::Force
00170     };
00171 
00172 static const int force_rule_to_combo[] =
00173     {
00174     0, // Unused
00175     0, // Don't Affect
00176     1 // Force
00177     };
00178 
00179 static const Rules::ForceRule combo_to_force_rule[] =
00180     {
00181     ( Rules::ForceRule )Rules::DontAffect,
00182     ( Rules::ForceRule )Rules::Force
00183     };
00184 
00185 static QString positionToStr( const QPoint& p )
00186     {
00187     if( p == invalidPoint )
00188         return QString::null;
00189     return QString::number( p.x()) + "," + QString::number( p.y());
00190     }
00191 
00192 static QPoint strToPosition( const QString& str )
00193     {            // two numbers, with + or -, separated by any of , x X :
00194     QRegExp reg( "\\s*([+-]?[0-9]*)\\s*[,xX:]\\s*([+-]?[0-9]*)\\s*" );
00195     if( !reg.exactMatch( str ))
00196         return invalidPoint;
00197     return QPoint( reg.cap( 1 ).toInt(), reg.cap( 2 ).toInt());
00198     }
00199 
00200 static QString sizeToStr( const QSize& s )
00201     {
00202     if( !s.isValid())
00203         return QString::null;
00204     return QString::number( s.width()) + "," + QString::number( s.height());
00205     }
00206 
00207 static QSize strToSize( const QString& str )
00208     {            // two numbers, with + or -, separated by any of , x X :
00209     QRegExp reg( "\\s*([+-]?[0-9]*)\\s*[,xX:]\\s*([+-]?[0-9]*)\\s*" );
00210     if( !reg.exactMatch( str ))
00211         return QSize();
00212     return QSize( reg.cap( 1 ).toInt(), reg.cap( 2 ).toInt());
00213     }
00214 
00215 //used for opacity settings
00216 static QString intToStr( const int& s )
00217     {
00218     if( s < 1 || s > 100 )
00219         return QString::null;
00220     return QString::number(s);
00221     }
00222  
00223 static int strToInt( const QString& str )
00224     {
00225     int tmp = str.toInt();
00226     if( tmp < 1 || tmp > 100 )
00227         return 100;
00228     return tmp;
00229     }    
00230     
00231 int RulesWidget::desktopToCombo( int d ) const
00232     {
00233     if( d >= 1 && d < desktop->count())
00234         return d - 1;
00235     return desktop->count() - 1; // on all desktops
00236     }
00237 
00238 int RulesWidget::comboToDesktop( int val ) const
00239     {
00240     if( val == desktop->count() - 1 )
00241         return NET::OnAllDesktops;
00242     return val + 1;
00243     }
00244 
00245 static int placementToCombo( Placement::Policy placement )
00246     {
00247     static const int conv[] = 
00248         {
00249         1, // NoPlacement
00250         0, // Default
00251         5, // Random
00252         2, // Smart
00253         3, // Cascade
00254         4, // Centered
00255         6, // ZeroCornered
00256         7, // UnderMouse
00257         8 // OnMainWindow
00258         };
00259     return conv[ placement ];
00260     }
00261 
00262 static Placement::Policy comboToPlacement( int val )
00263     {
00264     static const Placement::Policy conv[] =
00265         {
00266         Placement::Default,
00267         Placement::NoPlacement,
00268         Placement::Smart,
00269         Placement::Cascade,
00270         Placement::Centered,
00271         Placement::Random,
00272         Placement::ZeroCornered,
00273         Placement::UnderMouse,
00274         Placement::OnMainWindow
00275         };
00276     return conv[ val ];
00277     }
00278 
00279 static int moveresizeToCombo( Options::MoveResizeMode mode )
00280     {
00281     return mode == Options::Opaque ? 0 : 1;
00282     }
00283 
00284 static Options::MoveResizeMode comboToMoveResize( int val )
00285     {
00286     return val == 0 ? Options::Opaque : Options::Transparent;
00287     }
00288 
00289 static int typeToCombo( NET::WindowType type )
00290     {
00291     if( type < NET::Normal || type > NET::Splash )
00292         return 0; // Normal
00293     static const int conv[] =
00294         {
00295         0, // Normal
00296         7, // Desktop
00297     3, // Dock
00298     4, // Toolbar
00299         5, // Menu
00300     1, // Dialog
00301     8, // Override
00302         9, // TopMenu
00303     2, // Utility
00304     6  // Splash
00305         };
00306     return conv[ type ];
00307     }
00308 
00309 static NET::WindowType comboToType( int val )
00310     {
00311     static const NET::WindowType conv[] =
00312         {
00313         NET::Normal,
00314         NET::Dialog,
00315         NET::Utility,
00316         NET::Dock,
00317         NET::Toolbar,
00318         NET::Menu,
00319         NET::Splash,
00320         NET::Desktop,
00321         NET::Override,
00322         NET::TopMenu
00323         };
00324     return conv[ val ];
00325     }
00326 
00327 #define GENERIC_RULE( var, func, Type, type, uimethod, uimethod0 ) \
00328     if( rules->var##rule == Rules::Unused##Type##Rule ) \
00329         { \
00330         enable_##var->setChecked( false ); \
00331         rule_##var->setCurrentItem( 0 ); \
00332         var->uimethod0; \
00333         updateEnable##var(); \
00334         } \
00335     else \
00336         { \
00337         enable_##var->setChecked( true ); \
00338         rule_##var->setCurrentItem( type##_rule_to_combo[ rules->var##rule ] ); \
00339         var->uimethod( func( rules->var )); \
00340         updateEnable##var(); \
00341         }
00342 
00343 #define CHECKBOX_SET_RULE( var, func ) GENERIC_RULE( var, func, Set, set, setChecked, setChecked( false ))
00344 #define LINEEDIT_SET_RULE( var, func ) GENERIC_RULE( var, func, Set, set, setText, setText( "" ))
00345 #define COMBOBOX_SET_RULE( var, func ) GENERIC_RULE( var, func, Set, set, setCurrentItem, setCurrentItem( 0 ))
00346 #define CHECKBOX_FORCE_RULE( var, func ) GENERIC_RULE( var, func, Force, force, setChecked, setChecked( false ))
00347 #define LINEEDIT_FORCE_RULE( var, func ) GENERIC_RULE( var, func, Force, force, setText, setText( "" ))
00348 #define COMBOBOX_FORCE_RULE( var, func ) GENERIC_RULE( var, func, Force, force, setCurrentItem, setCurrentItem( 0 ))
00349 
00350 void RulesWidget::setRules( Rules* rules )
00351     {
00352     Rules tmp;
00353     if( rules == NULL )
00354         rules = &tmp; // empty
00355     description->setText( rules->description );
00356     wmclass->setText( rules->wmclass );
00357     whole_wmclass->setChecked( rules->wmclasscomplete );
00358     wmclass_match->setCurrentItem( rules->wmclassmatch );
00359     wmclassMatchChanged();
00360     role->setText( rules->windowrole );
00361     role_match->setCurrentItem( rules->windowrolematch );
00362     roleMatchChanged();
00363     types->setSelected( 0, rules->types & NET::NormalMask );
00364     types->setSelected( 1, rules->types & NET::DialogMask );
00365     types->setSelected( 2, rules->types & NET::UtilityMask );
00366     types->setSelected( 3, rules->types & NET::DockMask );
00367     types->setSelected( 4, rules->types & NET::ToolbarMask );
00368     types->setSelected( 5, rules->types & NET::MenuMask );
00369     types->setSelected( 6, rules->types & NET::SplashMask );
00370     types->setSelected( 7, rules->types & NET::DesktopMask );
00371     types->setSelected( 8, rules->types & NET::OverrideMask );
00372     types->setSelected( 9, rules->types & NET::TopMenuMask );
00373     title->setText( rules->title );
00374     title_match->setCurrentItem( rules->titlematch );
00375     titleMatchChanged();
00376     extra->setText( rules->extrarole );
00377     extra_match->setCurrentItem( rules->extrarolematch );
00378     extraMatchChanged();
00379     machine->setText( rules->clientmachine );
00380     machine_match->setCurrentItem( rules->clientmachinematch );
00381     machineMatchChanged();
00382     LINEEDIT_SET_RULE( position, positionToStr );
00383     LINEEDIT_SET_RULE( size, sizeToStr );
00384     COMBOBOX_SET_RULE( desktop, desktopToCombo );
00385     CHECKBOX_SET_RULE( maximizehoriz, );
00386     CHECKBOX_SET_RULE( maximizevert, );
00387     CHECKBOX_SET_RULE( minimize, );
00388     CHECKBOX_SET_RULE( shade, );
00389     CHECKBOX_SET_RULE( fullscreen, );
00390     COMBOBOX_FORCE_RULE( placement, placementToCombo );
00391     CHECKBOX_SET_RULE( above, );
00392     CHECKBOX_SET_RULE( below, );
00393     CHECKBOX_SET_RULE( noborder, );
00394     CHECKBOX_SET_RULE( skiptaskbar, );
00395     CHECKBOX_SET_RULE( skippager, );
00396     CHECKBOX_FORCE_RULE( acceptfocus, );
00397     CHECKBOX_FORCE_RULE( closeable, );
00398     LINEEDIT_FORCE_RULE( opacityactive, intToStr );
00399     LINEEDIT_FORCE_RULE( opacityinactive, intToStr );
00400     LINEEDIT_SET_RULE( shortcut, );
00401     COMBOBOX_FORCE_RULE( fsplevel, );
00402     COMBOBOX_FORCE_RULE( moveresizemode, moveresizeToCombo );
00403     COMBOBOX_FORCE_RULE( type, typeToCombo );
00404     CHECKBOX_FORCE_RULE( ignoreposition, );
00405     LINEEDIT_FORCE_RULE( minsize, sizeToStr );
00406     LINEEDIT_FORCE_RULE( maxsize, sizeToStr );
00407     CHECKBOX_FORCE_RULE( strictgeometry, );
00408     }
00409 
00410 #undef GENERIC_RULE
00411 #undef CHECKBOX_SET_RULE
00412 #undef LINEEDIT_SET_RULE
00413 #undef COMBOBOX_SET_RULE
00414 #undef CHECKBOX_FORCE_RULE
00415 #undef LINEEDIT_FORCE_RULE
00416 #undef COMBOBOX_FORCE_RULE
00417 
00418 #define GENERIC_RULE( var, func, Type, type, uimethod ) \
00419     if( enable_##var->isChecked()) \
00420         { \
00421         rules->var##rule = combo_to_##type##_rule[ rule_##var->currentItem() ]; \
00422         rules->var = func( var->uimethod()); \
00423         } \
00424     else \
00425         rules->var##rule = Rules::Unused##Type##Rule;
00426 
00427 #define CHECKBOX_SET_RULE( var, func ) GENERIC_RULE( var, func, Set, set, isChecked )
00428 #define LINEEDIT_SET_RULE( var, func ) GENERIC_RULE( var, func, Set, set, text )
00429 #define COMBOBOX_SET_RULE( var, func ) GENERIC_RULE( var, func, Set, set, currentItem )
00430 #define CHECKBOX_FORCE_RULE( var, func ) GENERIC_RULE( var, func, Force, force, isChecked )
00431 #define LINEEDIT_FORCE_RULE( var, func ) GENERIC_RULE( var, func, Force, force, text )
00432 #define COMBOBOX_FORCE_RULE( var, func ) GENERIC_RULE( var, func, Force, force, currentItem )
00433 
00434 Rules* RulesWidget::rules() const
00435     {
00436     Rules* rules = new Rules();
00437     rules->description = description->text();
00438     rules->wmclass = wmclass->text().utf8();
00439     rules->wmclasscomplete = whole_wmclass->isChecked();
00440     rules->wmclassmatch = static_cast< Rules::StringMatch >( wmclass_match->currentItem());
00441     rules->windowrole = role->text().utf8();
00442     rules->windowrolematch = static_cast< Rules::StringMatch >( role_match->currentItem());
00443     rules->types = 0;
00444     bool all_types = true;
00445     for( unsigned int i = 0;
00446          i < types->count();
00447          ++i )
00448         if( !types->isSelected( i ))
00449             all_types = false;
00450     if( all_types ) // if all types are selected, use AllTypesMask (for future expansion)
00451         rules->types = NET::AllTypesMask;
00452     else
00453         {
00454         rules->types |= types->isSelected( 0 ) ? NET::NormalMask : 0;
00455         rules->types |= types->isSelected( 1 ) ? NET::DialogMask : 0;
00456         rules->types |= types->isSelected( 2 ) ? NET::UtilityMask : 0;
00457         rules->types |= types->isSelected( 3 ) ? NET::DockMask : 0;
00458         rules->types |= types->isSelected( 4 ) ? NET::ToolbarMask : 0;
00459         rules->types |= types->isSelected( 5 ) ? NET::MenuMask : 0;
00460         rules->types |= types->isSelected( 6 ) ? NET::SplashMask : 0;
00461         rules->types |= types->isSelected( 7 ) ? NET::DesktopMask : 0;
00462         rules->types |= types->isSelected( 8 ) ? NET::OverrideMask : 0;
00463         rules->types |= types->isSelected( 9 ) ? NET::TopMenuMask : 0;
00464         }
00465     rules->title = title->text();
00466     rules->titlematch = static_cast< Rules::StringMatch >( title_match->currentItem());
00467     rules->extrarole = extra->text().utf8();
00468     rules->extrarolematch = static_cast< Rules::StringMatch >( extra_match->currentItem());
00469     rules->clientmachine = machine->text().utf8();
00470     rules->clientmachinematch = static_cast< Rules::StringMatch >( machine_match->currentItem());
00471     LINEEDIT_SET_RULE( position, strToPosition );
00472     LINEEDIT_SET_RULE( size, strToSize );
00473     COMBOBOX_SET_RULE( desktop, comboToDesktop );
00474     CHECKBOX_SET_RULE( maximizehoriz, );
00475     CHECKBOX_SET_RULE( maximizevert, );
00476     CHECKBOX_SET_RULE( minimize, );
00477     CHECKBOX_SET_RULE( shade, );
00478     CHECKBOX_SET_RULE( fullscreen, );
00479     COMBOBOX_FORCE_RULE( placement, comboToPlacement );
00480     CHECKBOX_SET_RULE( above, );
00481     CHECKBOX_SET_RULE( below, );
00482     CHECKBOX_SET_RULE( noborder, );
00483     CHECKBOX_SET_RULE( skiptaskbar, );
00484     CHECKBOX_SET_RULE( skippager, );
00485     CHECKBOX_FORCE_RULE( acceptfocus, );
00486     CHECKBOX_FORCE_RULE( closeable, );
00487     LINEEDIT_FORCE_RULE( opacityactive, strToInt );
00488     LINEEDIT_FORCE_RULE( opacityinactive, strToInt );
00489     LINEEDIT_SET_RULE( shortcut, );
00490     COMBOBOX_FORCE_RULE( fsplevel, );
00491     COMBOBOX_FORCE_RULE( moveresizemode, comboToMoveResize );
00492     COMBOBOX_FORCE_RULE( type, comboToType );
00493     CHECKBOX_FORCE_RULE( ignoreposition, );
00494     LINEEDIT_FORCE_RULE( minsize, strToSize );
00495     LINEEDIT_FORCE_RULE( maxsize, strToSize );
00496     CHECKBOX_FORCE_RULE( strictgeometry, );
00497     return rules;
00498     }
00499 
00500 #undef GENERIC_RULE
00501 #undef CHECKBOX_SET_RULE
00502 #undef LINEEDIT_SET_RULE
00503 #undef COMBOBOX_SET_RULE
00504 #undef CHECKBOX_FORCE_RULE
00505 #undef LINEEDIT_FORCE_RULE
00506 #undef COMBOBOX_FORCE_RULE
00507 
00508 #define STRING_MATCH_COMBO( type ) \
00509 void RulesWidget::type##MatchChanged() \
00510     { \
00511     edit_reg_##type->setEnabled( type##_match->currentItem() == Rules::RegExpMatch ); \
00512     type->setEnabled( type##_match->currentItem() != Rules::UnimportantMatch ); \
00513     }
00514 
00515 STRING_MATCH_COMBO( wmclass )
00516 STRING_MATCH_COMBO( role )
00517 STRING_MATCH_COMBO( title )
00518 STRING_MATCH_COMBO( extra )
00519 STRING_MATCH_COMBO( machine )
00520 
00521 #undef STRING_MATCH_COMBO
00522 
00523 void RulesWidget::detectClicked()
00524     {
00525     assert( detect_dlg == NULL );
00526     detect_dlg = new DetectDialog;
00527     connect( detect_dlg, SIGNAL( detectionDone( bool )), this, SLOT( detected( bool )));
00528     detect_dlg->detect( 0 );
00529     }
00530 
00531 void RulesWidget::detected( bool ok )
00532     {
00533     if( ok )
00534         {
00535         wmclass->setText( detect_dlg->selectedClass());
00536         wmclass_match->setCurrentItem( Rules::ExactMatch );
00537         wmclassMatchChanged(); // grrr
00538         whole_wmclass->setChecked( detect_dlg->selectedWholeClass());
00539         role->setText( detect_dlg->selectedRole());
00540         role_match->setCurrentItem( detect_dlg->selectedRole().isEmpty()
00541             ? Rules::UnimportantMatch : Rules::ExactMatch );
00542         roleMatchChanged();
00543         if( detect_dlg->selectedWholeApp())
00544             {
00545             for( unsigned int i = 0;
00546                  i < types->count();
00547                  ++i )
00548                 types->setSelected( i, true );
00549             }
00550         else
00551             {
00552             NET::WindowType type = detect_dlg->selectedType();
00553             for( unsigned int i = 0;
00554                  i < types->count();
00555                  ++i )
00556                 types->setSelected( i, false );
00557             types->setSelected( typeToCombo( type ), true );
00558             }
00559         title->setText( detect_dlg->selectedTitle());
00560         title_match->setCurrentItem( detect_dlg->titleMatch());
00561         titleMatchChanged();
00562         machine->setText( detect_dlg->selectedMachine());
00563         machine_match->setCurrentItem( Rules::UnimportantMatch );
00564         machineMatchChanged();
00565         // prefill values from to window to settings which already set
00566         const KWin::WindowInfo& info = detect_dlg->windowInfo();
00567         prefillUnusedValues( info );
00568         }
00569     delete detect_dlg;
00570     detect_dlg = NULL;
00571     detect_dlg_ok = ok;
00572     }
00573 
00574 #define GENERIC_PREFILL( var, func, info, uimethod ) \
00575     if( !enable_##var->isChecked()) \
00576         { \
00577         var->uimethod( func( info )); \
00578         }
00579 
00580 #define CHECKBOX_PREFILL( var, func, info ) GENERIC_PREFILL( var, func, info, setChecked )
00581 #define LINEEDIT_PREFILL( var, func, info ) GENERIC_PREFILL( var, func, info, setText )
00582 #define COMBOBOX_PREFILL( var, func, info ) GENERIC_PREFILL( var, func, info, setCurrentItem )
00583 
00584 void RulesWidget::prefillUnusedValues( const KWin::WindowInfo& info )
00585     {
00586     LINEEDIT_PREFILL( position, positionToStr, info.frameGeometry().topLeft() );
00587     LINEEDIT_PREFILL( size, sizeToStr, info.frameGeometry().size() );
00588     COMBOBOX_PREFILL( desktop, desktopToCombo, info.desktop() );
00589     CHECKBOX_PREFILL( maximizehoriz,, info.state() & NET::MaxHoriz );
00590     CHECKBOX_PREFILL( maximizevert,, info.state() & NET::MaxVert );
00591     CHECKBOX_PREFILL( minimize,, info.isMinimized() );
00592     CHECKBOX_PREFILL( shade,, info.state() & NET::Shaded );
00593     CHECKBOX_PREFILL( fullscreen,, info.state() & NET::FullScreen );
00594     //COMBOBOX_PREFILL( placement, placementToCombo );
00595     CHECKBOX_PREFILL( above,, info.state() & NET::KeepAbove );
00596     CHECKBOX_PREFILL( below,, info.state() & NET::KeepBelow );
00597     // noborder is only internal KWin information, so let's guess
00598     CHECKBOX_PREFILL( noborder,, info.frameGeometry() == info.geometry() );
00599     CHECKBOX_PREFILL( skiptaskbar,, info.state() & NET::SkipTaskbar );
00600     CHECKBOX_PREFILL( skippager,, info.state() & NET::SkipPager );
00601     //CHECKBOX_PREFILL( acceptfocus, );
00602     //CHECKBOX_PREFILL( closeable, );
00603     LINEEDIT_PREFILL( opacityactive, intToStr, 100 /*get the actual opacity somehow*/);
00604     LINEEDIT_PREFILL( opacityinactive, intToStr, 100 /*get the actual opacity somehow*/);
00605     //LINEEDIT_PREFILL( shortcut, );
00606     //COMBOBOX_PREFILL( fsplevel, );
00607     //COMBOBOX_PREFILL( moveresizemode, moveresizeToCombo );
00608     COMBOBOX_PREFILL( type, typeToCombo, info.windowType( SUPPORTED_WINDOW_TYPES_MASK ) );
00609     //CHECKBOX_PREFILL( ignoreposition, );
00610     LINEEDIT_PREFILL( minsize, sizeToStr, info.frameGeometry().size() );
00611     LINEEDIT_PREFILL( maxsize, sizeToStr, info.frameGeometry().size() );
00612     //CHECKBOX_PREFILL( strictgeometry, );
00613     }
00614 
00615 #undef GENERIC_PREFILL
00616 #undef CHECKBOX_PREFILL
00617 #undef LINEEDIT_PREFILL
00618 #undef COMBOBOX_PREFILL
00619 
00620 bool RulesWidget::finalCheck()
00621     {
00622     if( description->text().isEmpty())
00623         {
00624         if( !wmclass->text().isEmpty())
00625             description->setText( i18n( "Settings for %1" ).arg( wmclass->text()));
00626         else
00627             description->setText( i18n( "Unnamed entry" ));
00628         }
00629     bool all_types = true;
00630     for( unsigned int i = 0;
00631          i < types->count();
00632          ++i )
00633         if( !types->isSelected( i ))
00634             all_types = false;
00635     if( wmclass_match->currentItem() == Rules::UnimportantMatch && all_types )
00636         {
00637         if( KMessageBox::warningContinueCancel( topLevelWidget(),
00638             i18n( "You have specified the window class as unimportant.\n"
00639                   "This means the settings will possibly apply to windows from all applications. "
00640                   "If you really want to create a generic setting, it is recommended you at least "
00641                   "limit the window types to avoid special window types." )) != KMessageBox::Continue )
00642             return false;
00643         }
00644     return true;
00645     }
00646 
00647 void RulesWidget::prepareWindowSpecific( WId window )
00648     {
00649     tabs->setCurrentPage( 2 ); // geometry tab, skip tabs for window identification
00650     KWin::WindowInfo info( window, -1U, -1U ); // read everything
00651     prefillUnusedValues( info );
00652     }
00653 
00654 void RulesWidget::shortcutEditClicked()
00655     {
00656     EditShortcutDialog dlg( topLevelWidget());
00657     dlg.setShortcut( shortcut->text());
00658     if( dlg.exec() == QDialog::Accepted )
00659         shortcut->setText( dlg.shortcut());
00660     }
00661 
00662 RulesDialog::RulesDialog( QWidget* parent, const char* name )
00663 : KDialogBase( parent, name, true, i18n( "Edit Window-Specific Settings" ), Ok | Cancel )
00664     {
00665     widget = new RulesWidget( this );
00666     setMainWidget( widget );
00667     }
00668 
00669 // window is set only for Alt+F3/Window-specific settings, because the dialog
00670 // is then related to one specific window
00671 Rules* RulesDialog::edit( Rules* r, WId window )
00672     {
00673     rules = r;
00674     widget->setRules( rules );
00675     if( window != 0 )
00676         widget->prepareWindowSpecific( window );
00677     exec();
00678     return rules;
00679     }
00680 
00681 void RulesDialog::accept()
00682     {
00683     if( !widget->finalCheck())
00684         return;
00685     rules = widget->rules();
00686     KDialogBase::accept();
00687     }
00688 
00689 EditShortcut::EditShortcut( QWidget* parent, const char* name )
00690 : EditShortcutBase( parent, name )
00691     {
00692     }
00693 
00694 void EditShortcut::editShortcut()
00695     {
00696     ShortcutDialog dlg( KShortcut( shortcut->text()), topLevelWidget());
00697     if( dlg.exec() == QDialog::Accepted )
00698         shortcut->setText( dlg.shortcut().toString());
00699     }
00700 
00701 void EditShortcut::clearShortcut()
00702     {
00703     shortcut->setText( "" );
00704     }
00705 
00706 EditShortcutDialog::EditShortcutDialog( QWidget* parent, const char* name )
00707 : KDialogBase( parent, name, true, i18n( "Edit Shortcut" ), Ok | Cancel )
00708     {
00709     widget = new EditShortcut( this );
00710     setMainWidget( widget );
00711     }
00712 
00713 void EditShortcutDialog::setShortcut( const QString& cut )
00714     {
00715     widget->shortcut->setText( cut );
00716     }
00717 
00718 QString EditShortcutDialog::shortcut() const
00719     {
00720     return widget->shortcut->text();
00721     }
00722 
00723 ShortcutDialog::ShortcutDialog( const KShortcut& cut, QWidget* parent, const char* name )
00724     : KShortcutDialog( cut, false /*TODO???*/, parent, name )
00725     {
00726     }
00727 
00728 void ShortcutDialog::accept()
00729     {
00730     for( int i = 0;
00731          ;
00732          ++i )
00733         {
00734         KKeySequence seq = shortcut().seq( i );
00735         if( seq.isNull())
00736             break;
00737         if( seq.key( 0 ) == Key_Escape )
00738             {
00739             reject();
00740             return;
00741             }
00742         if( seq.key( 0 ) == Key_Space )
00743             { // clear
00744             setShortcut( KShortcut());
00745             KShortcutDialog::accept();
00746             return;
00747             }
00748         if( seq.key( 0 ).modFlags() == 0 )
00749             { // no shortcuts without modifiers
00750             KShortcut cut = shortcut();
00751             cut.setSeq( i, KKeySequence());
00752             setShortcut( cut );
00753             return;
00754             }
00755         }
00756     KShortcutDialog::accept();
00757     }
00758 
00759 } // namespace
00760 
00761 #include "ruleswidget.moc"
KDE Logo
This file is part of the documentation for kwin Library Version 3.4.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Apr 6 02:41:06 2005 by doxygen 1.4.0 written by Dimitri van Heesch, © 1997-2003