mirror of
https://github.com/xiaoyifang/goldendict-ng.git
synced 2024-11-27 15:24:05 +00:00
Implemented Dictionaries Pane, to show dicts in which results were found.
It is a separate detacheable pane, which could also be enabled/disabled, it tracks the current tab's contains, and lists those dictionaries that contributed their content to the current translation. Clicking on dictionary name jumps to the appropriate article from this dictionary, which improves the navigation flow. The Dictionaries Pane: * Shows both dictionaries' names and icons. * Does not consume resources when hidden. * Properly styled. * Properly handles app-wide shortcuts (Esc, Ctrl-L, Alt-D, Enter, Alt-Up/Down).
This commit is contained in:
parent
ade15f5d41
commit
3762f22e76
|
@ -366,6 +366,32 @@ QString ArticleView::getCurrentArticle()
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ArticleView::jumpToDictionary(QString const & dictName)
|
||||||
|
{
|
||||||
|
// Find the dictionary with the specified name
|
||||||
|
|
||||||
|
for( unsigned x = allDictionaries.size(); x--; )
|
||||||
|
{
|
||||||
|
|
||||||
|
if ( QString::fromUtf8( allDictionaries[ x ]->getName().c_str()) == dictName )
|
||||||
|
{
|
||||||
|
|
||||||
|
// Check that one of the articles belongs to the specified dictionary.
|
||||||
|
|
||||||
|
QStringList ids = getArticlesList();
|
||||||
|
for( QStringList::const_iterator i = ids.constBegin(); i != ids.constEnd(); ++i )
|
||||||
|
{
|
||||||
|
if ( allDictionaries[ x ]->getId() == i->toUtf8().data() ) {
|
||||||
|
setCurrentArticle( "gdfrom-" + *i, true );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ArticleView::setCurrentArticle( QString const & id, bool moveToIt )
|
void ArticleView::setCurrentArticle( QString const & id, bool moveToIt )
|
||||||
{
|
{
|
||||||
if ( !id.startsWith( "gdfrom-" ) )
|
if ( !id.startsWith( "gdfrom-" ) )
|
||||||
|
|
|
@ -142,7 +142,15 @@ public:
|
||||||
/// Closes search if it's open and returns true. Returns false if it
|
/// Closes search if it's open and returns true. Returns false if it
|
||||||
/// wasn't open.
|
/// wasn't open.
|
||||||
bool closeSearch();
|
bool closeSearch();
|
||||||
|
|
||||||
|
/// Jumps to the article specified by the dictionary name,
|
||||||
|
/// by executing a javascript code.
|
||||||
|
void jumpToDictionary( QString const & );
|
||||||
|
|
||||||
|
/// Returns all articles current present in view, as a list of dictionary
|
||||||
|
/// string ids.
|
||||||
|
QStringList getArticlesList();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void iconChanged( ArticleView *, QIcon const & icon );
|
void iconChanged( ArticleView *, QIcon const & icon );
|
||||||
|
@ -201,9 +209,6 @@ private:
|
||||||
/// returns 0.
|
/// returns 0.
|
||||||
unsigned getGroup( QUrl const & );
|
unsigned getGroup( QUrl const & );
|
||||||
|
|
||||||
/// Returns all articles current present in view, as a list of dictionary
|
|
||||||
/// string ids.
|
|
||||||
QStringList getArticlesList();
|
|
||||||
|
|
||||||
/// Returns current article in the view, in the form of "gdfrom-xxx" id.
|
/// Returns current article in the view, in the form of "gdfrom-xxx" id.
|
||||||
QString getCurrentArticle();
|
QString getCurrentArticle();
|
||||||
|
|
23
dictspanewidget.hh
Normal file
23
dictspanewidget.hh
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
/* This file is (c) 2008-2011 Konstantin Isakov <ikm@goldendict.org>
|
||||||
|
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
|
||||||
|
|
||||||
|
#ifndef __DICTSPANEWIDGET_HH_INCLUDED__
|
||||||
|
#define __DICTSPANEWIDGET_HH_INCLUDED__
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QSize>
|
||||||
|
|
||||||
|
/// A widget holding the contents of the 'Dictionaries pane' docklet.
|
||||||
|
class DictsPaneWidget: public QWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
DictsPaneWidget( QWidget * parent = 0 ): QWidget( parent )
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual QSize sizeHint() const
|
||||||
|
{ return QSize( 204, 204 ); }
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -161,7 +161,8 @@ HEADERS += folding.hh \
|
||||||
country.hh \
|
country.hh \
|
||||||
about.hh \
|
about.hh \
|
||||||
programs.hh \
|
programs.hh \
|
||||||
parsecmdline.hh
|
parsecmdline.hh \
|
||||||
|
dictspanewidget.hh
|
||||||
FORMS += groups.ui \
|
FORMS += groups.ui \
|
||||||
dictgroupwidget.ui \
|
dictgroupwidget.ui \
|
||||||
mainwindow.ui \
|
mainwindow.ui \
|
||||||
|
|
114
mainwindow.cc
114
mainwindow.cc
|
@ -26,6 +26,7 @@ MainWindow::MainWindow( Config::Class & cfg_ ):
|
||||||
trayIcon( 0 ),
|
trayIcon( 0 ),
|
||||||
groupLabel( &searchPaneTitleBar ),
|
groupLabel( &searchPaneTitleBar ),
|
||||||
groupList( &searchPaneTitleBar ),
|
groupList( &searchPaneTitleBar ),
|
||||||
|
foundInDictsLabel( &dictsPaneTitleBar ),
|
||||||
escAction( this ),
|
escAction( this ),
|
||||||
focusTranslateLineAction( this ),
|
focusTranslateLineAction( this ),
|
||||||
addTabAction( this ),
|
addTabAction( this ),
|
||||||
|
@ -68,6 +69,15 @@ MainWindow::MainWindow( Config::Class & cfg_ ):
|
||||||
|
|
||||||
ui.searchPane->setTitleBarWidget( &searchPaneTitleBar );
|
ui.searchPane->setTitleBarWidget( &searchPaneTitleBar );
|
||||||
|
|
||||||
|
// Make the dictionaries pane's titlebar
|
||||||
|
foundInDictsLabel.setText( tr( "Found in Dictionaries:" ) );
|
||||||
|
dictsPaneTitleBarLayout.addWidget( &foundInDictsLabel );
|
||||||
|
dictsPaneTitleBar.setLayout( &dictsPaneTitleBarLayout );
|
||||||
|
ui.dictsPane->setTitleBarWidget( &dictsPaneTitleBar );
|
||||||
|
|
||||||
|
connect( ui.dictsPane, SIGNAL( visibilityChanged( bool ) ),
|
||||||
|
this, SLOT( dictsPaneVisibilityChanged ( bool ) ) );
|
||||||
|
|
||||||
// Make the toolbar
|
// Make the toolbar
|
||||||
navToolbar = addToolBar( tr( "Navigation" ) );
|
navToolbar = addToolBar( tr( "Navigation" ) );
|
||||||
navToolbar->setObjectName( "navToolbar" );
|
navToolbar->setObjectName( "navToolbar" );
|
||||||
|
@ -154,9 +164,12 @@ MainWindow::MainWindow( Config::Class & cfg_ ):
|
||||||
this, SLOT( focusTranslateLine() ) );
|
this, SLOT( focusTranslateLine() ) );
|
||||||
|
|
||||||
ui.centralWidget->addAction( &escAction );
|
ui.centralWidget->addAction( &escAction );
|
||||||
|
ui.dictsPane->addAction( &escAction );
|
||||||
ui.searchPaneWidget->addAction( &escAction );
|
ui.searchPaneWidget->addAction( &escAction );
|
||||||
groupList.addAction( &escAction );
|
groupList.addAction( &escAction );
|
||||||
|
|
||||||
ui.centralWidget->addAction( &focusTranslateLineAction );
|
ui.centralWidget->addAction( &focusTranslateLineAction );
|
||||||
|
ui.dictsPane->addAction( &focusTranslateLineAction );
|
||||||
ui.searchPaneWidget->addAction( &focusTranslateLineAction );
|
ui.searchPaneWidget->addAction( &focusTranslateLineAction );
|
||||||
groupList.addAction( &focusTranslateLineAction );
|
groupList.addAction( &focusTranslateLineAction );
|
||||||
|
|
||||||
|
@ -239,6 +252,7 @@ MainWindow::MainWindow( Config::Class & cfg_ ):
|
||||||
// Populate 'View' menu
|
// Populate 'View' menu
|
||||||
|
|
||||||
ui.menuView->addAction( ui.searchPane->toggleViewAction() );
|
ui.menuView->addAction( ui.searchPane->toggleViewAction() );
|
||||||
|
ui.menuView->addAction( ui.dictsPane->toggleViewAction() );
|
||||||
ui.menuView->addSeparator();
|
ui.menuView->addSeparator();
|
||||||
ui.menuView->addAction( dictionaryBar.toggleViewAction() );
|
ui.menuView->addAction( dictionaryBar.toggleViewAction() );
|
||||||
ui.menuView->addAction( navToolbar->toggleViewAction() );
|
ui.menuView->addAction( navToolbar->toggleViewAction() );
|
||||||
|
@ -350,6 +364,9 @@ MainWindow::MainWindow( Config::Class & cfg_ ):
|
||||||
connect( ui.wordList, SIGNAL( itemSelectionChanged() ),
|
connect( ui.wordList, SIGNAL( itemSelectionChanged() ),
|
||||||
this, SLOT( wordListSelectionChanged() ) );
|
this, SLOT( wordListSelectionChanged() ) );
|
||||||
|
|
||||||
|
connect( ui.dictsList, SIGNAL( itemSelectionChanged() ),
|
||||||
|
this, SLOT( dictsListSelectionChanged() ) );
|
||||||
|
|
||||||
connect( &wordFinder, SIGNAL( updated() ),
|
connect( &wordFinder, SIGNAL( updated() ),
|
||||||
this, SLOT( prefixMatchUpdated() ) );
|
this, SLOT( prefixMatchUpdated() ) );
|
||||||
connect( &wordFinder, SIGNAL( finished() ),
|
connect( &wordFinder, SIGNAL( finished() ),
|
||||||
|
@ -360,6 +377,7 @@ MainWindow::MainWindow( Config::Class & cfg_ ):
|
||||||
|
|
||||||
ui.translateLine->installEventFilter( this );
|
ui.translateLine->installEventFilter( this );
|
||||||
ui.wordList->installEventFilter( this );
|
ui.wordList->installEventFilter( this );
|
||||||
|
ui.dictsList->installEventFilter(this);
|
||||||
|
|
||||||
if ( cfg.mainWindowGeometry.size() )
|
if ( cfg.mainWindowGeometry.size() )
|
||||||
restoreGeometry( cfg.mainWindowGeometry );
|
restoreGeometry( cfg.mainWindowGeometry );
|
||||||
|
@ -961,11 +979,14 @@ void MainWindow::pageLoaded( ArticleView * view )
|
||||||
|
|
||||||
if ( cfg.preferences.pronounceOnLoadMain )
|
if ( cfg.preferences.pronounceOnLoadMain )
|
||||||
pronounce( view );
|
pronounce( view );
|
||||||
|
|
||||||
|
updateFoundInDictsList();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::tabSwitched( int )
|
void MainWindow::tabSwitched( int )
|
||||||
{
|
{
|
||||||
updatePronounceAvailability();
|
updatePronounceAvailability();
|
||||||
|
updateFoundInDictsList();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::tabMenuRequested(QPoint pos)
|
void MainWindow::tabMenuRequested(QPoint pos)
|
||||||
|
@ -995,6 +1016,53 @@ void MainWindow::pronounce( ArticleView * view )
|
||||||
dynamic_cast< ArticleView & >( *( ui.tabWidget->currentWidget() ) ).playSound();
|
dynamic_cast< ArticleView & >( *( ui.tabWidget->currentWidget() ) ).playSound();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::dictsPaneVisibilityChanged( bool visible )
|
||||||
|
{
|
||||||
|
if (visible) {
|
||||||
|
updateFoundInDictsList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::updateFoundInDictsList()
|
||||||
|
{
|
||||||
|
if (!ui.dictsList->isVisible())
|
||||||
|
{
|
||||||
|
// nothing to do, the list is not visible
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.dictsList->clear();
|
||||||
|
|
||||||
|
if ( QWidget * cw = ui.tabWidget->currentWidget() )
|
||||||
|
{
|
||||||
|
ArticleView & view = dynamic_cast< ArticleView & >( *( cw ) );
|
||||||
|
|
||||||
|
QStringList ids = view.getArticlesList();
|
||||||
|
|
||||||
|
for( QStringList::const_iterator i = ids.constBegin(); i != ids.constEnd(); ++i)
|
||||||
|
{
|
||||||
|
// Find this dictionary
|
||||||
|
|
||||||
|
for( unsigned x = dictionaries.size(); x--; )
|
||||||
|
{
|
||||||
|
if ( dictionaries[ x ]->getId() == i->toUtf8().data() )
|
||||||
|
{
|
||||||
|
QString dictName = QString::fromUtf8( dictionaries[ x ]->getName().c_str() );
|
||||||
|
QListWidgetItem * item =
|
||||||
|
new QListWidgetItem(
|
||||||
|
dictionaries[ x ]->getIcon(),
|
||||||
|
dictName,
|
||||||
|
ui.dictsList, QListWidgetItem::Type );
|
||||||
|
item->setToolTip(dictName);
|
||||||
|
|
||||||
|
ui.dictsList->addItem( item );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::updatePronounceAvailability()
|
void MainWindow::updatePronounceAvailability()
|
||||||
{
|
{
|
||||||
bool pronounceEnabled = ui.tabWidget->count() > 0 &&
|
bool pronounceEnabled = ui.tabWidget->count() > 0 &&
|
||||||
|
@ -1343,7 +1411,34 @@ bool MainWindow::eventFilter( QObject * obj, QEvent * ev )
|
||||||
// Handle typing events used to initiate new lookups
|
// Handle typing events used to initiate new lookups
|
||||||
|
|
||||||
if ( keyEvent->modifiers() &
|
if ( keyEvent->modifiers() &
|
||||||
( Qt::ControlModifier | Qt::ShiftModifier | Qt::AltModifier | Qt::MetaModifier ) )
|
( Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier ) )
|
||||||
|
return false; // A non-typing modifier is pressed
|
||||||
|
|
||||||
|
if ( keyEvent->key() == Qt::Key_Space ||
|
||||||
|
keyEvent->key() == Qt::Key_Backspace ||
|
||||||
|
keyEvent->key() == Qt::Key_Tab )
|
||||||
|
return false; // Those key have other uses than to start typing
|
||||||
|
// or don't make sense
|
||||||
|
|
||||||
|
QString text = keyEvent->text();
|
||||||
|
|
||||||
|
if ( text.size() )
|
||||||
|
{
|
||||||
|
typingEvent( text );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (obj == ui.dictsList) {
|
||||||
|
if ( ev->type() == /*QEvent::KeyPress*/ 6 )
|
||||||
|
{
|
||||||
|
QKeyEvent * keyEvent = static_cast< QKeyEvent * >( ev );
|
||||||
|
|
||||||
|
// Handle typing events used to initiate new lookups
|
||||||
|
|
||||||
|
if ( keyEvent->modifiers() &
|
||||||
|
( Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier ) )
|
||||||
return false; // A non-typing modifier is pressed
|
return false; // A non-typing modifier is pressed
|
||||||
|
|
||||||
if ( keyEvent->key() == Qt::Key_Space ||
|
if ( keyEvent->key() == Qt::Key_Space ||
|
||||||
|
@ -1380,6 +1475,20 @@ void MainWindow::wordListSelectionChanged()
|
||||||
wordListItemActivated( selected.front() );
|
wordListItemActivated( selected.front() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::dictsListItemActivated( QListWidgetItem * item )
|
||||||
|
{
|
||||||
|
ArticleView & view = dynamic_cast< ArticleView & >( *( ui.tabWidget->currentWidget() ) );
|
||||||
|
view.jumpToDictionary( item->text() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::dictsListSelectionChanged()
|
||||||
|
{
|
||||||
|
QList< QListWidgetItem * > selected = ui.dictsList->selectedItems();
|
||||||
|
|
||||||
|
if ( selected.size() )
|
||||||
|
dictsListItemActivated( selected.front() );
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::openLinkInNewTab( QUrl const & url,
|
void MainWindow::openLinkInNewTab( QUrl const & url,
|
||||||
QUrl const & referrer,
|
QUrl const & referrer,
|
||||||
QString const & fromArticle,
|
QString const & fromArticle,
|
||||||
|
@ -1404,7 +1513,7 @@ void MainWindow::typingEvent( QString const & t )
|
||||||
focusTranslateLine();
|
focusTranslateLine();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( ui.searchPane->isFloating() )
|
if ( ui.searchPane->isFloating() || ui.dictsPane->isFloating() )
|
||||||
ui.searchPane->activateWindow();
|
ui.searchPane->activateWindow();
|
||||||
|
|
||||||
ui.translateLine->setText( t );
|
ui.translateLine->setText( t );
|
||||||
|
@ -1434,6 +1543,7 @@ void MainWindow::showTranslationFor( QString const & inWord,
|
||||||
view.showDefinition( inWord, group );
|
view.showDefinition( inWord, group );
|
||||||
|
|
||||||
updatePronounceAvailability();
|
updatePronounceAvailability();
|
||||||
|
updateFoundInDictsList();
|
||||||
|
|
||||||
// Add to history
|
// Add to history
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,10 @@ private:
|
||||||
QLabel groupLabel;
|
QLabel groupLabel;
|
||||||
GroupComboBox groupList;
|
GroupComboBox groupList;
|
||||||
|
|
||||||
|
QWidget dictsPaneTitleBar;
|
||||||
|
QHBoxLayout dictsPaneTitleBarLayout;
|
||||||
|
QLabel foundInDictsLabel;
|
||||||
|
|
||||||
/// Fonts saved before words zooming is in effect, so it could be reset back.
|
/// Fonts saved before words zooming is in effect, so it could be reset back.
|
||||||
QFont wordListDefaultFont, translateLineDefaultFont;
|
QFont wordListDefaultFont, translateLineDefaultFont;
|
||||||
|
|
||||||
|
@ -120,6 +124,8 @@ private:
|
||||||
|
|
||||||
void updatePronounceAvailability();
|
void updatePronounceAvailability();
|
||||||
|
|
||||||
|
void updateFoundInDictsList();
|
||||||
|
|
||||||
/// Updates word search request and active article view in response to
|
/// Updates word search request and active article view in response to
|
||||||
/// muting or unmuting dictionaries, or showing/hiding dictionary bar.
|
/// muting or unmuting dictionaries, or showing/hiding dictionary bar.
|
||||||
void applyMutedDictionariesState();
|
void applyMutedDictionariesState();
|
||||||
|
@ -232,6 +238,11 @@ private slots:
|
||||||
void wordListItemActivated( QListWidgetItem * );
|
void wordListItemActivated( QListWidgetItem * );
|
||||||
void wordListSelectionChanged();
|
void wordListSelectionChanged();
|
||||||
|
|
||||||
|
void dictsListItemActivated( QListWidgetItem * );
|
||||||
|
void dictsListSelectionChanged();
|
||||||
|
|
||||||
|
void dictsPaneVisibilityChanged ( bool );
|
||||||
|
|
||||||
/// Creates a new tab, which is to be populated then with some content.
|
/// Creates a new tab, which is to be populated then with some content.
|
||||||
ArticleView * createNewTab( bool switchToIt,
|
ArticleView * createNewTab( bool switchToIt,
|
||||||
QString const & name );
|
QString const & name );
|
||||||
|
|
|
@ -244,6 +244,33 @@
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QDockWidget" name="dictsPane">
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Dictionaries Pane</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="dockWidgetArea">
|
||||||
|
<number>2</number>
|
||||||
|
</attribute>
|
||||||
|
<widget class="DictsPaneWidget" name="dictsPaneWidget">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QListWidget" name="dictsList"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
<action name="dictionaries">
|
<action name="dictionaries">
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="resources.qrc">
|
<iconset resource="resources.qrc">
|
||||||
|
@ -381,6 +408,12 @@
|
||||||
<header>searchpanewidget.hh</header>
|
<header>searchpanewidget.hh</header>
|
||||||
<container>1</container>
|
<container>1</container>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>DictsPaneWidget</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>dictspanewidget.hh</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<tabstops>
|
<tabstops>
|
||||||
<tabstop>translateLine</tabstop>
|
<tabstop>translateLine</tabstop>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
MainWindow #searchPane #translateLine, MainWindow #searchPane #wordList
|
MainWindow #searchPane #translateLine, MainWindow #searchPane #wordList, MainWindow #dictsPane #dictsList
|
||||||
{
|
{
|
||||||
background: white;
|
background: white;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
MainWindow #searchPane #translateLine, MainWindow #searchPane #wordList
|
MainWindow #searchPane #translateLine, MainWindow #searchPane #wordList, MainWindow #dictsPane #dictsList
|
||||||
{
|
{
|
||||||
background: #fefdeb;
|
background: #fefdeb;
|
||||||
color: black;
|
color: black;
|
||||||
|
|
Loading…
Reference in a new issue